[bzoj1934]善意的投票

最小割,考虑最小割就是要将整张图分为两块,本题中就分别表示赞同和不赞同,那么首先一开始赞同的点向S连边,不赞同的点向T连边,如果这些点分到了另一边就要割掉这条边,朋友关系同理,连双向边同样表示分到两边要割掉这条边,跑最小割=最大流即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 305
 4 struct ji{
 5     int nex,to,len;
 6 }edge[N*N];
 7 queue<int>q;
 8 int E,n,m,x,y,head[N],work[N],d[N];
 9 void add(int x,int y,int z){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     edge[E].len=z;
13     head[x]=E++;
14     if (E&1)add(y,x,0);
15 }
16 bool bfs(){
17     memset(d,-1,sizeof(d));
18     q.push(0);
19     d[0]=0;
20     while (!q.empty()){
21         int k=q.front();
22         q.pop();
23         for(int i=head[k];i!=-1;i=edge[i].nex)
24             if ((edge[i].len)&&(d[edge[i].to]<0)){
25                 d[edge[i].to]=d[k]+1;
26                 q.push(edge[i].to);
27             }
28     }
29     return d[n+1]>=0;
30 }
31 int dfs(int k,int s){
32     if (k>n)return s;
33     int p;
34     for(int &i=work[k];i!=-1;i=edge[i].nex)
35         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
36             p=dfs(edge[i].to,min(s,edge[i].len));
37             if (p){
38                 edge[i].len-=p;
39                 edge[i^1].len+=p;
40                 return p;
41             }
42         }
43     return 0;
44 }
45 int main(){
46     scanf("%d%d",&n,&m);
47     memset(head,-1,sizeof(head));
48     for(int i=1;i<=n;i++){
49         scanf("%d",&x);
50         if (x)add(0,i,1);
51         else add(i,n+1,1);
52     }
53     for(int i=1;i<=m;i++){
54         scanf("%d%d",&x,&y);
55         add(x,y,1);
56         edge[E-1].len=1;
57     }
58     int ans=0;
59     while (bfs()){
60         memcpy(work,head,sizeof(head));
61         while (x=dfs(0,0x3f3f3f3f))ans+=x;
62     }
63     printf("%d",ans);
64 } 

原文地址:https://www.cnblogs.com/PYWBKTDA/p/11829966.html

时间: 2024-11-10 14:02:53

[bzoj1934]善意的投票的相关文章

C++之路进阶——最大流(善意的投票)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1646  Solved: 1006[

BZOJ 1934: [Shoi2007]Vote 善意的投票 最小割

1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1934 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票.我们定义一次投票的冲突数

1934: [Shoi2007]Vote 善意的投票

1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1174  Solved: 723[Submit][Status] Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票.我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所

[SHTSC 2007] 善意的投票

我就是来复习Dinic算法的,仅10天不写,我已经退化成写一遍+调试需要接近一个小时了,当然其中不乏在网上乱逛的时间… 赞成从S源点连一条单向边,反对向T汇点连一条单向边,朋友关系连双向边. 但是总感觉自己看到题目不能一下想到这是网络流,感觉这些题都是给一个图,求最优之类. program vote; type ptype=^node; node=record v,w,flow:longint; op,next:ptype; end; const maxn=310; var head:array

洛谷 P2057 善意的投票(网络流最小割)

P2057 善意的投票 题目描述 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票.我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数. 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小? 输入输出格式 输入格式: 文件的第一行只有两个整数n,m,保证有2≤n≤300,1≤m≤n(n-1)/2.其中

「SHOI2007」「Codevs2341」 善意的投票

2341 善意的投票 2007年省队选拔赛上海市队选拔赛 时间限制: 5 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票.我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数. 我们的问题就是,每位小朋友

luoguP2057善意的投票

理解下题意: 题意大致就是有n个人有两种不同的意见并且有许多朋友,需要让朋友间尽可能的统一意见(少发生冲突),如果一个人违反自己的本意也算冲突,求最少的冲突... 思路: 明眼人直接发现是最小割,两种意见可以看作源点S和T,我们需要做的是割最少的边使得S和T成为两个不同的集合,解释:割掉的边相当于1次冲突(因为若某边被割走,则显然这条边相连的两个点分别通向了S和T,所以算是一次冲突),当S和T还连通时则必然存在一条路径,这样肯定会有冲突,所以需要使得S和T孤立. 实现: 实现时这样建图:直接将S

BZOJ1934:[SHOI2007]善意的投票 &amp; BZOJ2768:[JLOI2010]冠军调查——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=1934 https://www.lydsy.com/JudgeOnline/problem.php?id=2768 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票.我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲

bzoj1934: [Shoi2007]Vote 善意的投票

一定要想到是最小割. 虚拟源点S连支持者容量为1,反对者连虚拟汇点容量为1,支持者连反对者容量为1. 割俩面的点,一面是支持,一面是反对,冲突数就是割(哥..雾). 最小冲突数就是最小割. #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn = 300 + 10; const int maxm = 100000 + 10; const int