Description
Input
Output
Sample Input
1 0 0
1 2
1 3
3 2
Sample Output
HINT
在第一个例子中,所有小朋友都投赞成票就能得到最优解
好久没做网络流了有点手生(其实还是因为菜
第一眼二分图最小割
第二眼emmm……
很容易想到同一阵营的分一边然后求最小割,
可是一个人改变主意的话和他的老铁们就冲突了咋整?
那么就同一阵营朋友间连双向边。
为什么是双向边呢?我觉得一篇题解写的非常清楚:
"若两个人有冲突,则只需要其中任意一个人改变意见就行了
简单说是让a同意b的意见或者b同意a的意见,
所以只需割掉一条边满足一种情况就可以了,
但是有两种情况,所以建双向边"
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<queue> 6 #define MAXM (1000000+10) 7 #define MAXN (30000+10) 8 using namespace std; 9 struct node 10 { 11 int Flow; 12 int next; 13 int to; 14 }edge[MAXM*2]; 15 int Depth[MAXN]; 16 int head[MAXN],num_edge; 17 int n,m,s,e,x,y,INF,a[MAXN]; 18 queue<int>q; 19 20 void add(int u,int v,int l) 21 { 22 edge[++num_edge].to=v; 23 edge[num_edge].Flow=l; 24 edge[num_edge].next=head[u]; 25 head[u]=num_edge; 26 } 27 28 bool Bfs(int s,int e) 29 { 30 memset(Depth,0,sizeof(Depth)); 31 q.push(s); 32 Depth[s]=1; 33 while (!q.empty()) 34 { 35 int x=q.front(); q.pop(); 36 for (int i=head[x];i!=0;i=edge[i].next) 37 if (!Depth[edge[i].to] && edge[i].Flow>0) 38 { 39 Depth[edge[i].to]=Depth[x]+1; 40 q.push(edge[i].to); 41 } 42 } 43 return Depth[e]; 44 } 45 46 int Dfs(int x,int low) 47 { 48 int Min,f=0; 49 if (x==e || low==0) 50 return low; 51 for (int i=head[x];i!=0;i=edge[i].next) 52 if (edge[i].Flow>0 && Depth[edge[i].to]==Depth[x]+1 && (Min=Dfs(edge[i].to,min(low,edge[i].Flow)))) 53 { 54 edge[i].Flow-=Min; 55 edge[((i-1)^1)+1].Flow+=Min; 56 low-=Min; 57 f+=Min; 58 if (low==0) return f; 59 } 60 if (!f) Depth[x]=-1; 61 return f; 62 } 63 64 int Dinic(int s,int e) 65 { 66 int Ans=0; 67 while (Bfs(s,e)) 68 Ans+=Dfs(s,0x7fffffff); 69 return Ans; 70 } 71 72 int main() 73 { 74 memset(&INF,0x7f,sizeof(INF)); 75 scanf("%d%d",&n,&m); 76 s=0,e=20001; 77 for (int i=1;i<=n;++i) 78 { 79 scanf("%d",&a[i]); 80 if (a[i]==1) add(0,i,1),add(i,0,0); 81 else add(i,e,1); add(e,i,0); 82 } 83 for (int i=1;i<=m;++i) 84 { 85 scanf("%d%d",&x,&y); 86 if (a[x]==a[y]) 87 { 88 add(x,y,1); add(y,x,0); 89 add(x,y,0); add(y,x,1); 90 } 91 else 92 { 93 if (a[x]==0) swap(x,y); 94 add(x,y,1); add(y,x,0); 95 } 96 } 97 printf("%d",Dinic(s,e)); 98 }