LOJ2421 NOIP2015 信息传递 【tarjan求最小环】
LOJ2421 NOIP2015 信息传递
题目大意就是给你一个有向图,求最小环
有一个很奇妙的性质叫做每个点只有一条出边
然后我们考虑对每个强联通分量进行考虑
发现每个强联通分量内的边数一定和点数相等
也就是说一个强连通的大小就是这个环的长度
然后就可以来一个很常规的tarjan算一下就好了
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200010 4 int prt[N],vis[N],n; 5 int cnt_scc=0,dfn[N],low[N],ind=0; 6 stack<int> st; 7 int ans=0x3f3f3f3f; 8 void tarjan(int u){ 9 st.push(u);vis[u]=1; 10 dfn[u]=low[u]=++ind; 11 int v=prt[u]; 12 if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]); 13 else if(vis[v])low[u]=min(low[u],dfn[v]); 14 if(low[u]!=dfn[u])return; 15 int tp,siz=0; 16 do{ 17 siz++; 18 tp=st.top(); 19 st.pop(); 20 vis[tp]=0; 21 }while(tp!=u); 22 if(siz!=1)ans=min(ans,siz); 23 } 24 int main(){ 25 scanf("%d",&n); 26 for(int i=1;i<=n;i++)scanf("%d",&prt[i]); 27 for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i); 28 printf("%d",ans); 29 return 0; 30 }