NOI2006最大获利

终于搞明白了……

x到y有边意味着选x必须选y,所以才会有闭合子图中一个点的后继一定也在这个闭合子图中。

接下来按照s连正权,负权连t就ok了

  1 type node=record
  2      go,next,c:longint;
  3      end;
  4 var i,n,m,s,t,max,tmp,ans,tot,x,y,z:longint;
  5     h,first,q,cur:array[0..100000] of longint;
  6     e:array[0..500000] of node;
  7 function min(x,y:longint):longint;
  8  begin
  9    if x<y then exit(x) else exit(y);
 10  end;
 11 procedure insert(x,y,z:longint);
 12  begin
 13    inc(tot);
 14    e[tot].go:=y;
 15    e[tot].c:=z;
 16    e[tot].next:=first[x];
 17    first[x]:=tot;
 18    inc(tot);
 19    e[tot].go:=x;
 20    e[tot].c:=0;
 21    e[tot].next:=first[y];
 22    first[y]:=tot;
 23  end;
 24 procedure init;
 25  begin
 26    readln(n,m);
 27    s:=0;t:=m+n+1;tot:=1;
 28    for i:=1 to n do
 29     begin
 30       read(x);
 31       insert(s,i,x);
 32     end;
 33    max:=0;
 34    for i:=1 to m do
 35     begin
 36       readln(x,y,z);inc(max,z);
 37       insert(n+i,t,z);
 38       insert(x,n+i,maxlongint>>2);
 39       insert(y,n+i,maxlongint>>2);
 40     end;
 41  end;
 42 function bfs:boolean;
 43  var i,x,y,head,tail:longint;
 44  begin
 45    fillchar(h,sizeof(h),0);
 46    head:=0;tail:=1;q[1]:=s;h[s]:=1;
 47    while head<tail do
 48     begin
 49       inc(head);
 50       x:=q[head];
 51       i:=first[x];
 52       while i<>0 do
 53         begin
 54           y:=e[i].go;
 55           if (h[y]=0) and (e[i].c<>0) then
 56            begin
 57              h[y]:=h[x]+1;
 58              inc(tail);
 59              q[tail]:=y;
 60            end;
 61           i:=e[i].next;
 62         end;
 63     end;
 64    exit(h[t]<>0);
 65  end;
 66 function dfs(x,f:longint):longint;
 67  var i,tmp,used:longint;
 68    begin
 69      if (x=t) or (f=0) then exit(f);
 70      tmp:=0;used:=0;
 71      i:=cur[x];
 72      while i<>0 do
 73        begin
 74          y:=e[i].go;
 75          if (e[i].c<>0) and (h[y]=h[x]+1) then
 76            begin
 77              tmp:=dfs(y,min(e[i].c,f-used));
 78              dec(e[i].c,tmp);
 79              inc(e[i xor 1].c,tmp);
 80              if e[i].c<>0 then cur[x]:=i;
 81              inc(used,tmp);
 82              if used=f then exit(f);
 83            end;
 84          i:=e[i].next;
 85        end;
 86      if used=0 then h[x]:=-1;
 87      exit(used);
 88    end;
 89 procedure dinic;
 90  begin
 91    ans:=0;
 92    while bfs do
 93      begin
 94        for i:=0 to t do cur[i]:=first[i];
 95        inc(ans,dfs(0,maxlongint>>2));
 96      end;
 97  end;
 98 procedure main;
 99  begin
100    dinic;
101    writeln(max-ans);
102  end;
103 begin
104   init;
105  main;
106 end.           

 

posted @ 2014-06-15 18:41  ZYF-ZYF  Views(189)  Comments(0Edit  收藏  举报