bzoj1934: [Shoi2007]Vote 善意的投票(显然最小割)

1934: [Shoi2007]Vote 善意的投票

题目:传送门

 

题解:

   明显的不能再明显的最小割。。。

   st连同意的,不同意的连ed

   朋友之间两两连边(即双向边)

   流量都为1...

   为啥:

   一个人只有两种选择...同意or不同意

   那么如果选择违背了个人意愿那么肯定要割掉一条边(起冲突了嘛),那就是流量啊...

   如果当前选择让两个盆友不在同一集合,那就产生了冲突,还是要割,还是流量啊...

   一A美滋滋~

代码水一发:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define qread(x) x=read()
 7 using namespace std;
 8 inline int read()
 9 {
10     int f=1,x=0;char ch;
11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return f*x;
14 }
15 struct node
16 {
17     int x,y,c,next,other;
18 }a[210000];int len,last[110000];
19 int n,m,st,ed;
20 void ins(int x,int y,int c)
21 {
22     int k1,k2;
23     k1=++len;
24     a[len].x=x;a[len].y=y;a[len].c=c;
25     a[len].next=last[x];last[x]=len;
26     
27     k2=++len;
28     a[len].x=y;a[len].y=x;a[len].c=0;
29     a[len].next=last[y];last[y]=len;
30     
31     a[k1].other=k2;
32     a[k2].other=k1;
33 }
34 int list[110000],h[110000],head,tail;
35 bool bt_h()
36 {
37     memset(h,0,sizeof(h));h[st]=1;
38     list[1]=st;head=1;tail=2;
39     while(head!=tail)
40     {
41         int x=list[head];
42         for(int k=last[x];k;k=a[k].next)
43         {
44             int y=a[k].y;
45             if(h[y]==0 && a[k].c>0)
46             {
47                 h[y]=h[x]+1;
48                 list[tail++]=y;
49             }
50         }
51         head++;
52     }
53     if(h[ed]>0)return true;
54     return false;
55 }
56 int find_flow(int x,int flow)
57 {
58     if(x==ed)return flow;
59     int s=0,t;
60     for(int k=last[x];k;k=a[k].next)
61     {
62         int y=a[k].y;
63         if(h[y]==h[x]+1 && a[k].c>0 && s<flow)
64         {
65             s+=t=find_flow(y,min(a[k].c,flow-s));
66             a[k].c-=t;a[a[k].other].c+=t;
67         }
68     }
69     if(s==0)h[x]=0;
70     return s;
71 }
72 int main()
73 {
74     qread(n);qread(m);
75     len=0;memset(last,0,sizeof(last));
76     st=110000-2;ed=st+1;
77     for(int i=1;i<=n;i++)
78     {
79         int x;qread(x);
80         if(x==1)ins(st,i,1);
81         else ins(i,ed,1);
82     }
83     for(int i=1;i<=m;i++)
84     {
85         int x,y;
86         qread(x);qread(y);
87         ins(x,y,1);
88         ins(y,x,1);
89     }
90     int ans=0;
91     while(bt_h())ans+=find_flow(st,999999999);
92     printf("%d\n",ans);
93     return 0;
94 }

 

posted @ 2017-12-29 13:38  CHerish_OI  阅读(213)  评论(0编辑  收藏  举报