Description
自行车赛在一个很大的地方举行,有N个镇,用1到N编号,镇与镇之间有M条单行道相连,起点设在镇1,终点设在镇2。
问从起点到终点一共有多少种不同的路线。两条路线只要不使用完全相同的道路就被认为是不同的。
Input
第一行两个整数:N和M(1<=N<=10000,1<=M<=100000),表示镇的数量和道路的数量。
接下来M行,每行包含两个不同的整数A和B,表示有一条从镇A到镇B的单行道。
两个镇之间有可能不止一条路连接。
Output
输出不同路线的数量,如果答案超过9位,只需输出最后9位数字。如果有无穷多的路线,输出“inf”。
Sample Input
输入1:
6 7
1 3
1 4
3 2
4 2
5 6
6 5
3 4
输入2:
6 8
1 3
1 4
3 2
4 2
5 6
6 5
3 4
4 3
Sample Output
输出1:
3
输出2:
inf
题解:
可以这样想:
- 如果两点之间有无限多种方案数,表示在两点间的必经之路上有一个环
- 对于环的处理我们考虑用tarjan算法求强连通分量且缩点建新图G
- 对新图G作拓扑排序并按拓扑序作递推
- 注意要取后9位且有前导零
递推公式:
f[i]=∑j=1nf[j]且j为i的一个父节点
经过多轮调♂戏试,我们可以发现
这道题并没有inf的数据点!!!!!
于是我们不考虑有inf的情况即可
代码
type
edge=record
x,y,next:longint;
end;
arr=array[1..100000]of edge;
const
p=1000000000;
var
n,m,t,maxE,maxG:longint;
comp,ind,low,dfn,num,ls,s:array[0..10000]of longint;
state:array[0..1000000]of longint;
v:array[1..10000]of boolean;
flag:boolean;
e,g:arr;
function min(x,y:longint):longint;
begin
min:=x;
if y<x then
min:=y;
end;
procedure add(var q:arr;var max,x,y:longint);
begin
inc(max);
q[max].x:=x;
q[max].y:=y;
q[max].next:=ls[x];
ls[x]:=max;
end;
procedure tarjan(x:longint);
var
i,y:longint;
begin
inc(t);
dfn[x]:=t;
low[x]:=t;
inc(s[0]);
s[s[0]]:=x;
v[x]:=true;
i:=ls[x];
while i>0 do
begin
y:=e[i].y;
if dfn[y]=0 then
begin
tarjan(y);
low[x]:=min(low[y],low[x]);
end
else
if v[y] then
low[x]:=min(low[x],dfn[y]);
i:=e[i].next;
end;
if dfn[x]=low[x] then
begin
inc(comp[0]);
repeat
y:=s[s[0]];
comp[y]:=comp[0];
v[y]:=false;
dec(s[0]);
until x=y;
end;
end;
procedure topsort;
var
i,head,tail:longint;
begin
fillchar(ind,sizeof(ind),0);
for i:=1 to maxE do
inc(ind[e[i].y]);
head:=0;
tail:=0;
for i:=1 to comp[0] do
if ind[i]=0 then
begin
inc(tail);
state[tail]:=i;
end;
num[comp[1]]:=1;
repeat
inc(head);
i:=ls[state[head]];
while i>0 do
with e[i] do
begin
dec(ind[y]);
num[y]:=num[y]+num[x];
if num[y]>=p then
begin
flag:=true;
num[y]:=num[y]mod p;
end;
if ind[y]=0 then
begin
inc(tail);
state[tail]:=y;
end;
i:=next;
end;
until head>=tail;
t:=tail;
end;
procedure print;
var
i:longint;
st:string;
begin
str(num[comp[2]],st);
if flag then
for i:=1 to 9-length(st) do write(0);
writeln(st);
end;
procedure main;
var
i:longint;
begin
for i:=1 to n do
if dfn[i]=0 then
tarjan(i);
fillchar(ls,sizeof(ls),0);
for i:=1 to maxE do
if comp[e[i].x]<>comp[e[i].y] then
add(g,maxG,comp[e[i].x],comp[e[i].y]);
maxE:=maxG;
e:=g;
topsort;
end;
procedure init;
var
i,x,y:longint;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
add(e,maxE,x,y);
end;
end;
begin
init;
main;
print;
end.