【NOIP2015】信息传递(强连通分量)

题意:找一张图中的最小环

O(n)

思路:强连通分量tarjan即可 注意环中节点数>1

 1 var head,vet,next,s,b,stack,low,dfn,flag:array[1..200000]of longint;
 2     n,i,ans,tot,id,top,time,x:longint;
 3 
 4 procedure add(a,b:longint);
 5 begin
 6  inc(tot);
 7  next[tot]:=head[a];
 8  vet[tot]:=b;
 9  head[a]:=tot;
10 end;
11 
12 function min(x,y:longint):longint;
13 begin
14  if x<y then exit(x);
15  exit(y);
16 end;
17 
18 procedure dfs(u:longint);
19 var e,v:longint;
20 begin
21  flag[u]:=1;
22  inc(top); stack[top]:=u;
23  inc(time); dfn[u]:=time; low[u]:=time;
24  e:=head[u];
25  while e<>0 do
26  begin
27   v:=vet[e];
28   if flag[v]=0 then
29   begin
30    dfs(v);
31    low[u]:=min(low[u],low[v]);
32   end
33    else if s[v]=0 then low[u]:=min(low[u],low[v]);
34   e:=next[e];
35  end;
36 
37  if low[u]=dfn[u] then
38  begin
39   inc(id); s[u]:=id; inc(b[id]);
40   while (top>0)and(stack[top]<>u) do
41   begin
42    s[stack[top]]:=id;
43    inc(b[id]);
44    stack[top]:=0;
45    dec(top);
46   end;
47   stack[top]:=0;
48   dec(top);
49  end;
50 end;
51 
52 begin
53  //assign(input,'1.in'); reset(input);
54  //assign(output,'1.out'); rewrite(output);
55  readln(n);
56  for i:=1 to n do
57  begin
58   read(x);
59   add(i,x);
60  end;
61  for i:=1 to n do
62   if flag[i]=0 then dfs(i);
63  ans:=n;
64  for i:=1 to id do
65   if (b[i]>1)and(b[i]<ans) then ans:=b[i];
66  if n=1 then writeln(0)
67   else writeln(ans);
68  //close(input);
69  //close(output);
70 end.

 

posted on 2016-09-21 20:54  myx12345  阅读(252)  评论(0编辑  收藏  举报

导航