P2754 [CTSC1999] 家园
来一篇 \(Pascal\)。
很显然分层之后就可以搞最大流了。
如果蒟蒻没有想错的话是这样子的 :
之前把 \(matrix[i,-1]\) 搞错了改了 \(1 h\)。把 \(ISAP\) 换成 \(Dinic\) 又换成 \(ISAP\) 以及清空各种优化数组和各种细节用了 \(\frac{1}{2} h\)。判的是大于等于而不是大于且忘记 \(-1\) 改了 \(1h\)(我\(zz\)了)。最后判有没有输出才拿了 \(100\) 分。以及一开始写用了 \(\frac{1}{2} h\)。
Uses math;
var
value,reach,next:array[-1..2100000] of longint;
gap,dis,cnt:array[-1..810000] of longint;
matrix:array[-1..210,-1..140] of longint;
capacity:array[-1..210] of longint;
n,m,i,j,l,r,nn,tmp,tot,now,node,time,need,sink,source,maxflow:longint;
procedure add(l,r,sum:longint);
begin
inc(tot); reach[tot]:=r; value[tot]:=sum; next[tot]:=cnt[l]; cnt[l]:=tot;
inc(tot); reach[tot]:=l; value[tot]:=8-8; next[tot]:=cnt[r]; cnt[r]:=tot;
end;
function Dfs(now,flow:longint):longint;
var i,k,mindis,ret:longint;
begin
mindis:=node-1; ret:=flow;
if now=sink then exit(flow);
i:=cnt[now];
while i<>-1 do
begin
if value[i]>0 then
begin
if dis[now]=dis[reach[i]]+1 then
begin
k:=Dfs(reach[i],min(ret,value[i]));
dec(value[i],k);inc(value[i xor 1],k);
dec(ret,k);
if dis[source]>=node then exit(flow-ret);
if ret=0 then break;
end;
mindis:=min(mindis,dis[reach[i]]);
end;
i:=next[i];
end;
if ret=flow then
begin
dec(gap[dis[now]]);
if gap[dis[now]]=0 then dis[source]:=node;
dis[now]:=mindis+1;
inc(gap[dis[now]]);
end;
exit(flow-ret);
end;
begin
filldword(cnt,sizeof(cnt) div 4,maxlongint*2+1); tot:=-1;
read(n,m,need); source:=0; sink:=9999; inc(n,2);
for i:=1 to m do
begin
read(capacity[i],matrix[i,-1]);
for j:=0 to matrix[i,-1]-1 do begin read(matrix[i,j]); inc(matrix[i,j],2); end;
end;
while tmp<666 do
begin
add(time*n+1,sink,maxlongint);
add(source,time*n+2,maxlongint);
if time>0 then
begin
for i:=1 to n do add((time-1)*n+i,time*n+i,maxlongint);
for i:=1 to m do
begin
l:=matrix[i,(time-1) mod matrix[i,-1]];
r:=matrix[i,time mod matrix[i,-1]];
add((time-1)*n+l,time*n+r,capacity[i]);
end;
end;
fillchar(gap,sizeof(gap),0);
fillchar(dis,sizeof(dis),0);
node:=sink+1; gap[source]:=node; maxflow:=0;
while dis[source]<node do inc(maxflow,Dfs(source,maxlongint));
inc(tmp,maxflow); inc(time);
if tmp>=need then break;
end;
if time>=666 then writeln(0) else
writeln(time-1);
end.
完结撒花!✿✿ヽ(゚▽゚)ノ✿