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

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

 

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

 

posted @ 2015-03-22 21:59  Macaulish  阅读(101)  评论(0编辑  收藏