bzoj 1934: [Shoi2007]Vote 善意的投票 (最小割)

时间:2023-05-11 21:50:49

原来是赞同的连源,原来是反对的连汇,然后是朋友的就连在一起,这样最小割就是割掉违背和谐的吧

type
arr=record
toward,next,cap:longint;
end;
const
maxm=;
maxn=;
var
first,col,gap,d,cur:array[..maxn]of longint;
edge:array[..maxm]of arr;
esum,tot,s,t,n:longint; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure add(j,k,l:longint);
begin
inc(esum);
edge[esum].toward:=k;
edge[esum].next:=first[j];
first[j]:=esum;
edge[esum].cap:=l;
end; procedure addedge(j,k,l:longint);
begin
add(j,k,l);
add(k,j,);
end; procedure into;
var
i,j,n,m:longint;
begin
readln(n,m);
fillchar(first,sizeof(first),);
esum:=-;
tot:=n+;
s:=n+;
t:=n+;
for i:= to n do begin
read(col[i]);
if col[i]= then addedge(s,i,)
else addedge(i,t,);
end;
while m> do begin
dec(m);
read(i,j);
if col[i]= then addedge(i,j,)
else addedge(j,i,);
end;
end; function sap(x,flow:longint):longint;
var
now,more,too,i:longint;
begin
if x=t then exit(flow);
i:=cur[x];
now:=;
while i>= do begin
too:=edge[i].toward;
if (d[x]=d[too]+) and (edge[i].cap>) then begin
more:=sap(too,min(edge[i].cap,flow-now));
dec(edge[i].cap,more);
inc(edge[i xor ].cap,more);
inc(now,more);
cur[x]:=i;
if now=flow then exit(flow);
end;
i:=edge[i].next;
end;
dec(gap[d[x]]);
if gap[d[x]]= then d[s]:=tot;
inc(d[x]);
inc(gap[d[x]]);
cur[x]:=first[x];
exit(now);
end; function maxflow:longint;
var
i,ans:longint;
begin
fillchar(d,sizeof(d),);
fillchar(gap,sizeof(gap),);
gap[]:=tot;
for i:= to n do cur[i]:=first[i];
ans:=;
while d[s]<tot do inc(ans,sap(s,maxlongint));
exit(ans);
end; begin
into;
writeln(maxflow);
end.