bzoj1638[Usaco2007 Mar]Cow Traffic (first code)
求出走到每个点有的方法数a[i],再求出每个点到终点的方法数b[i]。
每条边走的 次数=a[u[i]]*b[v[i]] 。
可以用类spfa按照拓扑序求a[i],把入度为0的点都入栈然后a[e[j]]=a[e[j]]+a[q[h]]
求b[i]可以把边反向重新spfa一遍。
[toggle Title="code "]
[pascal]
uses math;
var
u,v,rud,next,e,head:Array[1..50000]of longint;
f,ff:array[1..50000]of int64;
ans:int64;
i,j,n,m,ee,h,t:longint;
a:array[1..100000]of longint;
procedure swap(var aa,bb:longint);
var tt:longint;
begin
tt:=aa;aa:=bb;bb:=tt;
end;
procedure add(u,v:longint);
begin
inc(ee);next[ee]:=head[u];head[u]:=ee;e[ee]:=v;
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(u[i],v[i]);
if u[i]>v[i] then swap(u[i],v[i]);
add(u[i],v[i]);
inc(rud[v[i]]);
end;
h:=1; t:=0;
for i:=1 to n do
if rud[i]=0 then
begin
inc(t);a[t]:=i;f[i]:=1;
end;
while h<=t do
begin
j:=head[a[h]];
while j<>0 do
begin
f[e[j]]:=f[e[j]]+f[a[h]];
dec(rud[e[j]]);
if rud[e[j]]=0 then
begin
inc(t);a[t]:=e[j];
end;
j:=next[j];
end;
inc(h);
end;
fillchar(head,sizeof(head),0);ee:=0;
fillchar(rud,sizeof(rud),0);
for i:=1 to m do
begin
add(v[i],u[i]);
inc(rud[u[i]]);
end;
h:=1; t:=0;
for i:=1 to n do
if rud[i]=0 then
begin
inc(t);a[t]:=i;ff[i]:=1;
end;
while h<=t do
begin
j:=head[a[h]];
while j<>0 do
begin
ff[e[j]]:=ff[e[j]]+ff[a[h]];
dec(rud[e[j]]);
if rud[e[j]]=0 then
begin
inc(t);a[t]:=e[j];
end;
j:=next[j];
end;
inc(h);
end;
for i:=1 to m do
if f[u[i]]*ff[v[i]]>ans then ans:=f[u[i]]*ff[v[i]];
writeln(ans);
end.
[/pascal]
[/toggle]
-------------------------------------------------------------------------
花有重开日,人无再少年