最小割的经典模型,体现出最小割的基本定义,把两个集合划分的最小代价
把一开始同意的人连源点,不同意的连汇点,有关系的人之间连边,流量都为1
不难发现,割两点(人)间的边就相当于朋友之间发生冲突
割到连源汇点的边就相当于与原来意愿不同
所以解决问题的方案等于图中的一个割
则最少冲突数=最小割=最大流
1 type node=record 2 point,flow,next:longint; 3 end; 4 var edge:array[0..400010] of node; 5 cur,p,pre,numh,h:array[0..2010] of longint; 6 ans,len,i,j,x,y,n,m:longint; 7 8 procedure add(x,y,f:longint); 9 begin 10 inc(len); 11 edge[len].point:=y; 12 edge[len].flow:=f; 13 edge[len].next:=p[x]; 14 p[x]:=len; 15 end; 16 17 procedure sap; 18 var tmp,u,i,j,neck,f,q:longint; 19 begin 20 u:=0; 21 numh[0]:=n+1; 22 fillchar(pre,sizeof(pre),255); 23 fillchar(cur,sizeof(cur),255); 24 while h[0]<n+1 do 25 begin 26 if u=n then 27 begin 28 i:=0; 29 while i<>n do 30 begin 31 j:=cur[i]; 32 dec(edge[j].flow); 33 inc(edge[j xor 1].flow); 34 i:=edge[j].point; 35 end; 36 inc(ans); 37 u:=0; 38 end; 39 q:=-1; 40 i:=p[u]; 41 while i<>-1 do 42 begin 43 j:=edge[i].point; 44 if (edge[i].flow>0) and (h[u]=h[j]+1) then 45 begin 46 q:=i; 47 break; 48 end; 49 i:=edge[i].next; 50 end; 51 if q<>-1 then 52 begin 53 cur[u]:=q; 54 pre[j]:=u; 55 u:=j; 56 end 57 else begin 58 dec(numh[h[u]]); 59 if numh[h[u]]=0 then break; 60 i:=p[u]; 61 tmp:=n+1; 62 while i<>-1 do 63 begin 64 j:=edge[i].point; 65 if (edge[i].flow>0) then tmp:=min(tmp,h[j]); 66 i:=edge[i].next; 67 end; 68 h[u]:=tmp+1; 69 inc(numh[h[u]]); 70 if u<>0 then u:=pre[u]; 71 end; 72 end; 73 end; 74 75 begin 76 readln(n,m); 77 len:=-1; 78 fillchar(p,sizeof(p),255); 79 for i:=1 to n do 80 begin 81 read(x); 82 if x=0 then 83 begin 84 add(0,i,1); 85 add(i,0,0); 86 end 87 else begin 88 add(i,n+1,1); 89 add(n+1,i,0); 90 end; 91 end; 92 for i:=1 to m do 93 begin 94 readln(x,y); 95 add(x,y,1); 96 add(y,x,0); 97 add(y,x,1); 98 add(x,y,0); 99 end; 100 inc(n); 101 sap; 102 writeln(ans); 103 end.