Description
众所周知,交通情况是大家在日常生活中比较关心的问题。一条道路所允许的最大同时平行车辆数称为这条道路的最大吞吐量,我们假定这里都是双向道路。而我们经常要想知道两个站之间的最大总吞吐量。
由于你的才华横溢,过于出众,于是你就被交通部任命设计这个交通部的查询软件,允许市民查询目前城市的任意两个站之间的最大总吞吐量。
Input
输输入的第一行包括两个整数N和M,分别表示该城市的站点个数和道路的个数。
接下去有M行,每行有三个整数u、v、c(1<=u、v<=N,1<=c<=10^4),表示u和v站点之间有一条道路,且吞吐量为c。
然后一行有一个整数Q。代表市民的查询次数。
接下去有Q行,每行有两个整数s、t(1<=s、t<=N),表示市民的一个查询。
50%的数据保证N<=50,Q<=10000
100%的数据保证N<=300 和Q<=100000
Output
对于每组查询(s、t),输出s到t的最大总吞吐量。
Input
2 1
1 2 2
2
1 2
2 1
Output
2
2
在读入图的时候,先把任意两个点之间的最大流求出来,用dist[i,j]保存,然后在查询的时候,只需要直接输出就行了。。。
一个最小割,要注意fillchar的使用,赋最大值的时候用fillchar(f,sizeof(f),127)或fillchar(f,sizeof(f),$7f),就是赋成maxlongint;赋成-1是fillchar(f,sizeof(f),255);(正确性有待考证),不过最好再加个 div 2,免得256.。。。。
另外,这道题还有一个坑爹的地方是,两个点之间不只一条边。。。其实noi的题大多都有这样的陷阱,所以,除非题目特别说明,还是当做不只一条边来做。。。。。
var n,m,ans,q,flow,s,t,maxn:longint; f,dist,g:array[0..500,0..500]of longint; dis,now,fa,fan,pre,sum:array[0..500]of longint; v:array[0..500]of boolean; procedure init; var i,j,x,y,c:longint; begin fillchar(g,sizeof(g),0); readln(n,m); for i:=1 to m do begin readln(x,y,c); if c>f[x,y] then begin g[x,y]:=g[x,y]+c; g[y,x]:=g[y,x]+c; end; end; maxn:=maxlongint div 4; end; procedure sap; var i,j,k,flow,minn:longint;vis:boolean; begin ans:=0; fillchar(sum,sizeof(sum),0); fillchar(dis,sizeof(dis),0); for i:=1 to n do now[i]:=1; sum[0]:=n; i:=s;flow:=maxn; while dis[s]<n do begin fan[i]:=flow; vis:=false; for j:=now[i] to n do if (f[i,j]>0)and(dis[i]=dis[j]+1) then begin now[i]:=j; vis:=true; if f[i,j]<flow then flow:=f[i,j]; pre[j]:=i; i:=j; if i=t then begin ans:=ans+flow; while i<>s do begin k:=pre[i]; f[k,i]:=f[k,i]-flow; f[i,k]:=f[i,k]+flow; i:=k; end; flow:=maxn end; break; end; if vis then continue; minn:=maxn; for j:=1 to n do if (f[i,j]>0)and(dis[j]<minn) then begin now[i]:=j;minn:=dis[j]; end; dec(sum[dis[i]]); if sum[dis[i]]=0 then exit; dis[i]:=minn+1; inc(sum[dis[i]]); if i<>s then begin i:=pre[i];flow:=fan[i]; end; end; end; function min(a,b:longint):longint; begin if a>b then exit(b) else exit(a); end; procedure dfs(i:longint); var j:longint; begin v[i]:=true; for j:=1 to n do if (f[i,j]>0)and(not v[j]) then dfs(j); end; procedure ask; var i,x,y:longint; begin readln(q); for i:=1 to q do begin readln(x,y); if x=y then writeln(0) else writeln(dist[x,y]); end; end; procedure main; var i,j:longint; begin fillchar(dist,sizeof(dist),127 div 2); for i:=1 to n do fa[i]:=1; for i:=2 to n do begin f:=g; s:=fa[i];t:=i; sap; fillchar(v,sizeof(v),0); dfs(s); for j:=i+1 to n do if not v[j] then fa[j]:=i; for j:=1 to i-1 do begin dist[j,i]:=min(dist[j,fa[i]],ans); dist[i,j]:=dist[j,i]; end; end; ask; end; begin assign(input,'traffic.in');reset(input); assign(output,'traffic.out');rewrite(output); init; main; close(input);close(output); end.