1934: [Shoi2007] Vote Goodwill Vote
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2609 Solved: 1638
[ Submit ][ Status ][ Discuss ]
Description
Input
Output
Sample Input
1 0 0
1 2
1 3
3 2
Sample Output
HINT
In the first example, the optimal solution is obtained by all the children voting yes
Solution: After reading the meaning of the question, I was confused, and after reading the solution, I was still confused. .
Understand the meaning of the following:
The meaning of the question is roughly that there are n people who have two different opinions and many friends. It is necessary to make the friends as unified as possible (less conflicts). If one person violates his original intention, it is also a conflict, and seeks the least conflict. . .
Ideas:
The discerning person directly finds that it is the minimum cut. The two opinions can be regarded as the source points S and T. What we need to do is to cut the minimum edge to make S and T two different sets. Explanation: The cut edge is equivalent to 1 conflict (Because if an edge is cut off, it is obvious that the two points connected by this edge lead to S and T respectively, so it is a conflict), when S and T are still connected, there must be a path, so there must be conflict, so S and T need to be isolated.
accomplish:
The map is constructed like this: directly connect S to those who agree, T to those who disagree, and if the two are friends, connect a two-way edge between them (some people don't understand here: if two people have conflicts , you only need any one of them to change their opinions. Simply put, it is to make a agree with b’s opinion or b agree with a’s opinion, so it is enough to cut off one edge to satisfy one situation, but there are two situations, So build two sides). The last thing is to seek the minimum cut, and it is ok to directly apply the template with the maximum flow.
Code:
#include<bits/stdc++.h> using namespace std; int n,m,ans,S,T,tot=1,inf=100000000,e[500000],next[500000],head[500000],jia[500000],d[10000],q[200000]; void build(int t,int k,int s){ to++; e[tot]=k;jia[tot]=s; next[tot]=head[t];head[t]=tot; } int dfs (int u, int s) { int flow=0,s1=0; if(u==T)return s; for(int i=head[u];i;i=next[i]){ int v=e[i]; if(d[v]==d[u]+1&&jia[i]){ s1 = dfs (v, min (s, jia [i])); if(!s1)continue; flow+=s1;s-=s1; jia[i]-=s1;jia[i^1]+=s1; if(!s)break; } } if(!s)d[u]=-1; return flow; } int bfs(){ memset(d,-1,sizeof(d)); int l=0,r=1; q[1]=S;d[S]=0; while(l<r){ l++; int u=q[l]; for(int i=head[u];i;i=next[i]) if(d[e[i]]==-1&&jia[i]){ d[e[i]]=d[u]+1; q[++r]=e[i]; } } return d[T]!=-1; } int main(){ int i,t,k; scanf("%d%d",&n,&m); S=n+1;T=n+2; for(i=1;i<=n;i++){ scanf("%d",&t); if(t==1){ build(S,i,1); build(i,S,0);} else { build(i,T,1);build(T,i,0);} } for(i=1;i<=m;i++){ scanf("%d%d",&t,&k); build(t,k,1);build(k,t,0); build(k,t,1);build(t,k,0); } while(bfs())ans+=dfs(S,inf); printf("%d",ans); }