[bzoj]1934: [Shoi2007]Vote 善意的投票


原题链接: 善意的投票

题目大意:
选定每个人投的票的种类,使冲突最少。冲突数定义为:边的两端票种不一样的边数+违背自己意愿的个数。
理解题意:
可以把每个人都看成点。

  • 若他想投同意票,则从源点向他连边。
  • 若他想投反对票,则从他向汇点连边。
  • 朋友之间,连正反流量都为1的双向边。

那么我们的目标就是把这么多人分成两个不同的集合(一个同意一个反对)。我们可以发现,如果我们记两个点之间有流量为这两个人投相同的票。可以发现,把这么多人分成两个集合的代价就是这个图的最小割(理解下)。

那么就是最大流==最小割,模板套上去就行了。

下面是代码:

#include 
#include 
#include 
#include 
#include 
using namespace std;
const int M=200000,N=309,inf=(1<<31)-1;
int n,m,ver[M],head[N],next[M],edge[M],x,y,f,cnt=1,d[N],s,t;
int maxflow=0,flow;
queue  q;
void add(int x,int y,int a);
bool bfs();
int dinic(int x,int flow);
int main()
{
	//freopen("data.in","r",stdin);
	cin>>n>>m;
	s=0,t=n+1;
	for(int i=1;i<=n;i++){
		cin>>f;
		if(f)add(s,i,1),add(i,s,0);
		else add(i,t,1),add(t,i,0);

	}
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		add(x,y,1);
		add(y,x,1);
	}
	while(bfs()){
		while((flow=dinic(s,inf))){maxflow+=flow;}
	}
	cout<