1934: [Shoi2007]Vote 善意的投票

来源:互联网 发布:淘宝怎么看行业类目 编辑:程序博客网 时间:2024/06/08 01:01

Description

幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?

题解:

st->要睡觉的(流量为1)->ed(流量为0)

st->不要睡觉的(流量为0)->ed(流量为1)

好盆友互相连流量为1的边。

#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cstring>#include<queue>using namespace std;#define inf 1e9const int N=90310;int n,m;int st,ed;struct node{int x,y,z,next,other;}sa[N<<1];int len=0,first[N];void ins(int x,int y,int z){len++;sa[len].x=x;sa[len].y=y;sa[len].z=z;sa[len].next=first[x];first[x]=len;sa[len].other=len+1;len++;sa[len].x=y;sa[len].y=x;sa[len].z=0;sa[len].next=first[y];first[y]=len;sa[len].other=len-1;}queue<int>q;  int h[N];  bool bt()  {      memset(h,0,sizeof(h));h[st]=1;      q.push(st);      while(!q.empty())      {          int x=q.front();q.pop();          for(int i=first[x];i!=-1;i=sa[i].next)          {              int y=sa[i].y;              if(sa[i].z>0&&h[y]==0)              {                  h[y]=h[x]+1;                  q.push(y);              }          }      }      if(h[ed]==0) return false;      return true;  }  int getans(int x,int f)  {      if(x==ed) return f;      int s=0,o;      for(int i=first[x];i!=-1;i=sa[i].next)      {          int y=sa[i].y;          if(sa[i].z>0&&h[y]==h[x]+1&&f>s)          {              o=getans(y,min(f-s,sa[i].z));              s+=o;              sa[i].z-=o;              sa[sa[i].other].z+=o;          }      }      if(s==0) h[x]=0;      return s;  }  int main(){scanf("%d%d",&n,&m);st=0;ed=n+1;int x;memset(first,-1,sizeof(first));for(int i=1;i<=n;i++){scanf("%d",&x);if(x==0) ins(st,i,1),ins(i,ed,0);else ins(i,ed,1),ins(st,i,0);}int y;for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);ins(x,y,1);ins(y,x,1);}int ans=0;while(bt()){ans+=getans(st,inf);}printf("%d\n",ans);}


原创粉丝点击