还是二分图,源点 S 汇点 T , x[i]->y[i] 流量 1 权值 -cost 作为限制不重点, y[i]->x[i+1] /y[i]->x[i+n] 流量 inf 权值 0 为边, S->x[1] 流量 2 权值 0 为起点, y[n*n]->T 流量 2 权值 0 为终点, x[1]->y[1]/x[n*n]->y[n*n] 流量 1 权值 0 方便回来的时候不重复计算cost。这样的话最短路找增广路,最短路径值的相反数即为最大值,本题是最大费用最大流。
1 const maxe=1000000; inf=1000000000; 2 type 3 node=record 4 next,t,cap,cost:longint; 5 end; 6 var time,n,k,s,t,ans,temp,cnt:longint; 7 b:array[0..maxe] of node; 8 head,go,f,d:array[0..maxe] of longint; 9 p:array[0..maxe] of boolean; 10 procedure add(u,v,x,y:longint); 11 begin 12 inc(cnt); 13 with b[cnt] do 14 begin 15 next:=head[u]; 16 t:=v; 17 cap:=x; 18 cost:=y; 19 end; 20 head[u]:=cnt; 21 end; 22 procedure insert(u,v,x,y:longint); 23 begin 24 add(u,v,x,y); 25 add(v,u,0,-y); 26 end; 27 procedure intit; 28 var i,j,k,now,temp:longint; 29 begin 30 cnt:=-1; k:=n*n; s:=0; t:=2*k+1; ans:=0; 31 fillchar(head,sizeof(head),255); 32 fillchar(b,sizeof(b),255); 33 for i:=1 to n do 34 begin 35 for j:=1 to n do 36 begin 37 read(temp); now:=(i-1)*n+j; 38 insert(now,now+k,1,-temp); 39 if i<>n then insert(now+k,now+n,inf,0); 40 if j<>n then insert(now+k,now+1,inf,0); 41 end; 42 readln; 43 end; 44 insert(s,1,2,0); 45 insert(1,k+1,1,0); 46 insert(k,2*k,1,0); 47 insert(2*k,t,2,0); 48 readln(n); 49 end; 50 function spfa:longint; 51 var e,v,l,r,point:longint; 52 begin 53 fillchar(p,sizeof(p),true); 54 fillchar(go,sizeof(go),255); 55 for l:=s to t do d[l]:=inf; 56 l:=1; r:=1; f[1]:=s; p[s]:=false; d[s]:=0; 57 while l<=r do 58 begin 59 point:=f[l]; 60 e:=head[point]; 61 while e<>-1 do 62 begin 63 v:=b[e].t; 64 if (d[v]>d[point]+b[e].cost) and (b[e].cap>0) then 65 begin 66 d[v]:=d[point]+b[e].cost; 67 go[v]:=e; 68 if p[v] then 69 begin 70 p[v]:=false; 71 inc(r); 72 f[r]:=v; 73 end; 74 end; 75 e:=b[e].next; 76 end; 77 inc(l); 78 p[point]:=true; 79 end; 80 if d[t]<>inf then exit(-d[t]) 81 else exit(-1); 82 end; 83 function min(a,b:longint):longint; 84 begin if a>b then exit(b) else exit(a); end; 85 function delete:longint; 86 var now,flow:longint; 87 begin 88 now:=t; flow:=inf; 89 while go[now]<>-1 do 90 begin 91 flow:=min(flow,b[go[now]].cap); 92 now:=b[go[now] xor 1].t; 93 end; 94 now:=t; 95 while go[now]<>-1 do 96 begin 97 dec(b[go[now]].cap,flow); 98 inc(b[go[now] xor 1].cap,flow); 99 now:=b[go[now] xor 1].t; 100 end; 101 exit(flow); 102 end; 103 begin 104 readln(n); 105 while not(eof) do 106 begin 107 intit; 108 temp:=spfa; 109 while temp>0 do 110 begin 111 inc(ans,temp*delete); 112 temp:=spfa; 113 end; 114 writeln(ans); 115 end; 116 end.
其实代码里面乘的delete也是不需要的(因为最大流一定为1)。
(转载请注明出处:http://www.cnblogs.com/Kalenda/)
时间: 2024-10-25 20:23:19