poj2186

奶牛来奶牛去的,用图论说白了就是

找统计有向图有多少个点,其他每个点都能到达这个点

考虑到一个特性,在一个强联通分量中,如果一个点能被其他所有点到达,那必定这个分量中其他点也一定符合要求

于是我们考虑用tarjan缩点(将一个强连通分量看做一个点)

缩点后,如果存在只有一个出度为0的点(必定存在,否则就被tarjan缩成1个点)

那么显然答案就是这个点的规模

如果有两个以上的出度为0的点,那么必然的这两个点必不能相互到达,答案就是不能存在

问题得解

 1 type link=^node;
 2      node=record
 3        data:longint;
 4        next:link;
 5      end;
 6 var w:array[0..10010] of link;
 7     dfn,low,fa,st,size,cd:array[0..10010] of longint;
 8     f,v:array[0..10010] of boolean;
 9     s,sum,i,j,y,x,n,m,t,h:longint;
10     p:link;
11 procedure add(x,y:longint);
12   var p:link;
13   begin
14     new(p);
15     p^.data:=y;
16     p^.next:=w[x];
17     w[x]:=p;
18   end;
19 
20 procedure tarjan(x:longint);
21   var y:longint;
22       p:link;
23   begin
24     inc(t);
25     inc(h);
26     f[x]:=true;
27     v[x]:=true;
28     st[t]:=x;
29     dfn[x]:=h;
30     low[x]:=h;
31     p:=w[x];
32     while p<>nil do
33     begin
34       y:=p^.data;
35       if not v[y] then
36       begin
37         tarjan(y);
38         low[x]:=min(low[x],low[y]);
39       end
40       else if f[y] then low[x]:=min(low[x],low[y]);
41       p:=p^.next;
42     end;
43     if low[x]=dfn[x] then   //找到一个强连通分量
44     begin
45       inc(s);
46       while st[t+1]<>x do
47       begin
48         y:=st[t];
49         f[y]:=false;
50         fa[y]:=s;           //缩点,记录规模
51         inc(size[s]);
52         dec(t);
53       end;
54     end;
55   end;
56 
57 begin
58   readln(n,m);
59   for i:=1 to m do
60   begin
61     readln(x,y);
62     add(x,y);
63   end;
64   s:=0;
65   for i:=1 to n do
66     if not v[i] then tarjan(i);
67   fillchar(cd,sizeof(cd),0);
68   for i:=1 to n do
69   begin
70     p:=w[i];
71     while p<>nil do
72     begin
73       y:=p^.data;
74       if fa[y]<>fa[i] then inc(cd[fa[i]]);  //统计缩点后的出度
75       p:=p^.next;
76     end;
77   end;
78   sum:=0;
79   y:=0;
80   for i:=1 to s do
81     if cd[i]=0 then
82     begin
83       inc(sum);
84       y:=i;
85       if sum>1 then break;
86     end;
87   if (sum>1) or (sum=0) then writeln(0)
88   else writeln(size[y]);
89 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473283.html