bzoj1934: [Shoi2007]Vote goodwill vote

1934: [Shoi2007] Vote Goodwill Vote

Time Limit:  1 Sec   Memory Limit:  64 MB
Submit:  2609   Solved:  1638
[ Submit ][ Status ][ Discuss ]

Description

There are n children in kindergarten who plan to vote to decide whether to take a nap or not. For them, the issue was not very important, so they decided to promote the spirit of humility. Although everyone has their own opinions, in order to take care of the thoughts of their friends, they can also vote against their original wishes. We define the number of conflicts in a vote as the total number of conflicts between good friends plus all the people who conflict with their original will. Our question is, how should each child vote to minimize the number of conflicts?

Input

The first line has only two integers n and m, which are guaranteed to be 2≤n≤300 and 1≤m≤n(n-1)/2. Among them, n represents the total number of people, and m represents the logarithm of good friends. The second line of the file contains n integers. The ith integer represents the wishes of the ith child. When it is 1, it means agreeing to sleep, and when it is 0, it means opposing sleep. Next, there are m lines in the file, and each line has two integers i, j. Indicates that i, j are a pair of good friends, and we guarantee that any two pairs of i, j will not be repeated.

Output

Just output an integer, the smallest possible number of collisions.

Sample Input

3 3
1 0 0
1 2
1 3
3 2

Sample Output

1

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);
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324725252&siteId=291194637