[TyvjP1413]费用流模板裸题
拆点即可。
在一个宽M,长N的矩阵中,请你编一个程序,n次从矩阵的左上角走到矩阵的右下角,每到一处,就取走该处的数字,请你选择一
种走法使取得的数字的和最大,并输出其最大值。其中:3<=M<=20 M<=N<=100 1<=n<=10测试数据 #1: Accepted, time=15ms, mem=1154KB, score=10
测试数据 #2: Accepted, time=0ms, mem=1154KB, score=10
测试数据 #3: Accepted, time=15ms, mem=1154KB, score=10
测试数据 #4: Accepted, time=0ms, mem=1154KB, score=10
测试数据 #5: Accepted, time=15ms, mem=1154KB, score=10
测试数据 #6: Accepted, time=0ms, mem=1154KB, score=10
测试数据 #7: Accepted, time=0ms, mem=1154KB, score=10
测试数据 #8: Accepted, time=0ms, mem=1158KB, score=10
测试数据 #9: Accepted, time=0ms, mem=1150KB, score=10
测试数据 #10: Accepted, time=0ms, mem=1150KB, score=10
Time = 45ms Mem = 1158KB Score= 100
program p1413; Const inf=10000000; Type rec=record s,e,c,w,flow,next:longint; end; Var v:array[0..4002] of boolean; a:array[0..8002] of rec; b,q,d,cur:array[0..4002] of longint; n,m,k,i,j,st,tar,va,top:longint; Function poi2num(x,y:longint;isin:boolean):longint;inline;//num 1~2mn begin exit((x-1)*m*2+(y-1)*2+2-ord(isin)); end; Function min(a,b:longint):longint;inline;begin if a<b then exit(a);exit(b); end; Procedure addedge(p,q,ww,cost:longint); begin inc(top); with a[top] do begin s:=p; e:=q; w:=ww; c:=cost; next:=b[p]; end; b[p]:=top; end; Procedure Add(p,q,w,cost:longint); begin addedge(p,q,w,cost); addedge(q,p,0,-cost); end; Function spfa:boolean; var close,open,x,u,i:longint; begin fillchar(v,sizeof(v),false); fillchar(d,sizeof(d),$ff); fillchar(cur,sizeof(cur),0); q[1]:=st; close:=0;open:=1; v[st]:=true;d[st]:=0; while close<>open do begin close:=close mod n+1; x:=q[close]; u:=b[x]; while u<>b[0] do begin if (d[a[u].e]<d[x]+a[u].c) and (a[u].flow<a[u].w) then begin d[a[u].e]:=d[x]+a[u].c; cur[a[u].e]:=u; if not v[a[u].e] then begin open:=open mod n+1; v[a[u].e]:=true; q[open]:=a[u].e; end; end; u:=a[u].next; end; v[x]:=false; end; exit(not(d[tar]=d[0])); end; Function Addflow:longint; var u,y,delta:longint; begin delta:=maxlongint; addflow:=0; u:=tar; y:=a[cur[u]].s; while u<>st do begin delta:=min(delta,a[cur[u]].w-a[cur[u]].flow); u:=y; y:=a[cur[y]].s; end; u:=tar; y:=a[cur[u]].s; while u<>st do begin inc(a[cur[u]].flow,delta); inc(addflow,a[cur[u]].c*delta); dec(a[cur[u] xor 1].flow,delta); u:=y; y:=a[cur[y]].s; end; end; Function costflow:longint; begin costflow:=0; while spfa do inc(costflow,addflow); end; begin fillchar(b,sizeof(b),$ff); readln(k,m,n); top:=-1; for i:=1 to n do begin for j:=1 to m do begin read(va); Add(poi2num(i,j,true),poi2num(i,j,false),1,va); if (i=n) and (j=m) then Add(poi2num(n,m,true),poi2num(n,m,false),k-1,0) else if (i=1) and (j=1) then Add(poi2num(1,1,true),poi2num(1,1,false),k-1,0) else add(poi2num(i,j,true),poi2num(i,j,false),inf,0); if i<n then Add(poi2num(i,j,false),poi2num(i+1,j,true),inf,0); if j<m then Add(poi2num(i,j,false),poi2num(i,j+1,true),inf,0); end; readln; end; st:=1;tar:=2*m*n; n:=2*m*n; writeln(costflow); end.