【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.
null