[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.
原文地址:https://www.cnblogs.com/htfy/p/3076373.html