var t,ii,i,j,n,cost,top,tail,min,tt,ttf:longint;
pre,d:array[1..1000]of longint;
b:array[1..10000]of longint;
flag:array[1..1000]of boolean;
f,c:array[1..200,1..200]of longint;
begin
read(t);
for ii:=1 to t do
begin
fillchar(f,sizeof(f),0);
fillchar(c,sizeof(c),0);
read(n);
for i:=2 to n+1 do
for j:=n+2 to n+n+1 do
begin
read(c[i,j]);
c[j,i]:=-c[i,j];
f[i,j]:=1;
f[j,i]:=0;
end;
for i:=1 to n do
for j:=1 to n do
read(tt);
for i:=2 to n+1 do
begin
c[1,i]:=0;
c[i,1]:=0;
f[1,i]:=1;
f[i,1]:=0;
end;
for i:=n+2 to 2*n+1 do
begin
c[i,2*n+2]:=0;
c[2*n+2,i]:=0;
f[i,2*n+2]:=1;
f[2*n+2,i]:=0;
end;
ttf:=0;
cost:=0;
while true do begin
top:=1;tail:=1;
b[top]:=1;
fillchar(flag,sizeof(flag),true);
for i:=1 to n+n+2 do d[i]:=maxlongint;
fillchar(pre,sizeof(pre),0);
flag[1]:=false;
pre[1]:=-1;
d[1]:=0;
repeat
for i:=1 to n+n+2 do
if b[top]<>i then
if f[b[top],i]>0 then
if c[b[top],i]+d[b[top]]<d[i] then
begin
d[i]:=c[b[top],i]+d[b[top]];
pre[i]:=b[top];
if flag[i] then begin
tail:=tail+1;
b[tail]:=i;
flag[i]:=false;
end;
end;
flag[b[top]]:=true;
top:=top+1;
until top>tail;
if d[n+n+2]=maxlongint then break;
i:=n+n+2;
min:=maxlongint;
while pre[i]<>-1 do
begin
if min>f[pre[i],i] then min:=f[pre[i],i];
i:=pre[i];
end;
i:=n+n+2;
while pre[i]<>-1 do
begin
f[i,pre[i]]:=f[i,pre[i]]+min;
f[pre[i],i]:=f[pre[i],i]-min;
cost:=cost+c[pre[i],i]*min;
i:=pre[i];
end;
ttf:=ttf+min;
// writeln(cost);
end;
writeln(cost*cost);
// writeln(ttf);
end;
readln;readln;
end.
加一个源点连向所有左边的点,加一个汇点连向所有右边的点,边的费用为0,流量为1。
中间的边费用为c,流量为1