题意:n个点,m条有向边,从每个入度为0的点走到编号为n的点,求经过次数最多的边的经过次数
根据乘法原理易知:一条边(a,b)的经过次数=入度为0的点到a的路径条数*b到编号为n的路径条数
正反两次建图,分别跑两次dfs处理出即可
pascal同志记得开Q-(也可能是本蒟蒻写丑了)
{$Q-}
type
rec=record
a,b:longint;
end;
var
n,m,ll :longint;
last,f,g :array[0..5010] of longint;
pre,other :array[0..50010] of longint;
i :longint;
ans :longint;
l :array[0..50010] of rec;
procedure connect(x,y:longint);
begin
inc(ll);
pre[ll]:=last[x];
last[x]:=ll;
other[ll]:=y;
end;
procedure dfs1(x:longint);
var
p,q:longint;
begin
q:=last[x];
if q=0 then
begin
f[x]:=1; exit;
end;
while (q<>0) do
begin
p:=other[q];
if f[p]=0 then dfs1(p);
inc(f[x],f[p]);
q:=pre[q];
end;
end;
procedure dfs2(x:longint);
var
p,q:longint;
begin
q:=last[x];
if q=0 then
begin
g[x]:=1; exit;
end;
while (q<>0) do
begin
p:=other[q];
if g[p]=0 then dfs2(p);
inc(g[x],g[p]);
q:=pre[q];
end;
end;
begin
read(n,m);
for i:=1 to m do read(l[i].a,l[i].b);
for i:=1 to m do connect(l[i].b,l[i].a);
dfs1(n);
ll:=0;
for i:=1 to n do last[i]:=0;
for i:=1 to m do connect(l[i].a,l[i].b);
for i:=1 to n do if g[i]=0 then dfs2(i);
ans:=0;
for i:=1 to m do
if (f[l[i].a]*g[l[i].b]>ans) then ans:=f[l[i].a]*g[l[i].b];
writeln(ans);
end.
——by Eirlys