标签:
还是二分图,源点 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/)
标签:
原文地址:http://www.cnblogs.com/Kalenda/p/4864971.html