把这个式子弄清楚就知道这是最小割了
相当于,选某个点i有收入ai,i,会损失ci,
如果i,j都被选则有额外收入ai,j+aj,i
明显,对每个点i,连(s,i,∑ai,j) (i,t,ci)
对每对i,j连边(i,j,ai,j),没了
1 const inf=100000007; 2 type node=record 3 po,next,flow:longint; 4 end; 5 6 var e:array[0..2000010] of node; 7 p,numh,h,cur,pre,d:array[0..510] of longint; 8 t,len,ans,i,j,n,m,x,s:longint; 9 10 procedure add(x,y,f:longint); 11 begin 12 inc(len); 13 e[len].po:=y; 14 e[len].flow:=f; 15 e[len].next:=p[x]; 16 p[x]:=len; 17 end; 18 19 procedure build(x,y,f:longint); 20 begin 21 add(x,y,f); 22 add(y,x,0); 23 end; 24 25 function min(a,b:longint):longint; 26 begin 27 if a>b then exit(b) else exit(a); 28 end; 29 30 function sap:longint; 31 var u,i,j,tmp,neck,q:longint; 32 begin 33 numh[0]:=t+1; 34 for i:=0 to t do 35 cur[i]:=p[i]; 36 u:=0; sap:=0; neck:=inf; 37 while h[0]<t+1 do 38 begin 39 d[u]:=neck; 40 i:=cur[u]; 41 while i<>-1 do 42 begin 43 j:=e[i].po; 44 if (e[i].flow>0) and (h[u]=h[j]+1) then 45 begin 46 neck:=min(neck,e[i].flow); 47 pre[j]:=u; 48 cur[u]:=i; 49 u:=j; 50 if u=t then 51 begin 52 sap:=sap+neck; 53 while u<>0 do 54 begin 55 u:=pre[u]; 56 j:=cur[u]; 57 dec(e[j].flow,neck); 58 inc(e[j xor 1].flow,neck); 59 end; 60 neck:=inf; 61 end; 62 break; 63 end; 64 i:=e[i].next; 65 end; 66 if i=-1 then 67 begin 68 dec(numh[h[u]]); 69 if numh[h[u]]=0 then break; 70 q:=-1; 71 tmp:=t; 72 i:=p[u]; 73 while i<>-1 do 74 begin 75 j:=e[i].po; 76 if e[i].flow>0 then 77 if tmp>h[j] then 78 begin 79 q:=i; 80 tmp:=h[j]; 81 end; 82 i:=e[i].next; 83 end; 84 h[u]:=tmp+1; 85 inc(numh[h[u]]); 86 cur[u]:=q; 87 if u<>0 then 88 begin 89 u:=pre[u]; 90 neck:=d[u]; 91 end; 92 end; 93 end; 94 end; 95 96 begin 97 len:=-1; 98 fillchar(p,sizeof(p),255); 99 readln(n); 100 t:=n+1; 101 for i:=1 to n do 102 begin 103 s:=0; 104 for j:=1 to n do 105 begin 106 read(x); 107 s:=s+x; 108 build(i,j,x); 109 end; 110 build(0,i,s); 111 ans:=ans+s; 112 end; 113 for i:=1 to n do 114 begin 115 read(x); 116 build(i,t,x); 117 end; 118 writeln(ans-sap); 119 end.
时间: 2024-10-18 06:26:18