题意:给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)
现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,
这样一共走K次,现在要求K次所达到的方格的数的和最大。
n<=50,k<=10
思路:费用流
将每个点裂成一个出点和一个入点(i,j,1..2),这个思路与最大流类似
(i,j,1)->(i,j,2) 连两条边:
容量为1,费用为a[i,j]
容量为K,费用为0
(i,j,2)->(i+1,j,1)连容量为K,费用为0的边 (i,j+1)类似
(n,n,2)->T 连流量为K,费用为0的边限制流量
跑最大费用最大流就行了,其实就是SPFA的三角不等式改个方向
var fan:array[..]of longint;
q:array[..]of longint;
head,vet,next,len1,len2:array[..]of longint;
pre:array[..,..]of longint;
inq:array[..]of boolean;
dis:array[..]of longint;
a:array[..,..]of longint;
num:array[..,..,..]of longint;
n,m,k1,i,j,k,tot,s,source,src:longint;
ans:int64; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure add(a,b,c,d:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len1[tot]:=c;
len2[tot]:=d;
head[a]:=tot; inc(tot);
next[tot]:=head[b];
vet[tot]:=a;
len1[tot]:=;
len2[tot]:=-d;
head[b]:=tot;
end; function spfa:boolean;
var u,t,w,i,e,v:longint;
begin
for i:= to s do
begin
dis[i]:=-maxlongint;
inq[i]:=false;
end;
t:=; w:=; q[]:=source; inq[source]:=true; dis[source]:=;
while t<w do
begin
inc(t); u:=q[t mod (s+)];
inq[u]:=false;
e:=head[u];
while e<> do
begin
v:=vet[e];
if (len1[e]>)and(dis[u]+len2[e]>dis[v]) then
begin
pre[v,]:=u; pre[v,]:=e;
dis[v]:=dis[u]+len2[e];
if not inq[v] then
begin
inc(w); q[w mod (s+)]:=v;
inq[v]:=true;
end;
end;
e:=next[e];
end;
end;
if dis[src]=-maxlongint then exit(false)
else exit(true);
end; procedure mcf;
var k,e:longint;
t:int64;
begin
k:=src; t:=maxlongint;
while k<>source do
begin
e:=pre[k,]; k:=pre[k,];
t:=min(t,len1[e]);
end;
k:=src;
while k<>source do
begin
e:=pre[k,];
len1[e]:=len1[e]-t;
len1[fan[e]]:=len1[fan[e]]+t;
ans:=ans+t*len2[e];
k:=pre[k,];
end;
end; begin
assign(input,'codevs1227.in'); reset(input);
assign(output,'codevs1227.out'); rewrite(output);
readln(n,k1);
for i:= to do
if i mod = then fan[i]:=i+
else fan[i]:=i-;
for i:= to n do
for j:= to n do read(a[i,j]);
for i:= to n do
for j:= to n do
for k:= to do
begin
inc(s); num[i,j,k]:=s;
end;
for i:= to n do
for j:= to n do
begin
add(num[i,j,],num[i,j,],,a[i,j]);
add(num[i,j,],num[i,j,],k1,);
if j+<=n then add(num[i,j,],num[i,j+,],k1,);
if i+<=n then add(num[i,j,],num[i+,j,],k1,);
end;
source:=; src:=s+; inc(s);
add(num[n,n,],src,k1,);
while spfa do mcf;
writeln(ans);
close(input);
close(output);
end.