- 题目要求:找最小的环,所以直接dfs搜索。
- 每次从未找过的点出发,从这个点沿着有向边往下,当碰到已经经过的点,说明有环,这时可以计算这个环的点的个数,即当前点的搜索深度-以搜过的点的深度+1.
一个点被搜过,就可以搜完整个子图,下一次搜到是说明这个连接图里的最小环之前已经找过了,因此不做理会。
Codes
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 200005
using namespace std;
struct edge{
int to,next;
}e[maxn];
int vis[maxn],deepth[maxn],last[maxn];
int tmp,i,n,ans,cnt,tot;
void add(int x,int y)
{
tot++;
e[tot].to=y;
e[tot].next=last[x];
last[x]=tot;
}
void dfs(int u,int fa)
{
vis[u]=cnt;
deepth[u]=deepth[fa]+1;
for (int i=last[u];i;i=e[i].next)
{
int v=e[i].to;
if (!vis[v]) dfs(v,u);
else
{
if (vis[v]==cnt)ans=min(ans,deepth[u]-deepth[v]+1);
}
}
}
int main(){
tot=0;
ans=1e9;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&tmp),add(i,tmp);
cnt=0;
deepth[0]=0;
for (int i=1;i<=n;i++)
{
if (!vis[i]) cnt++,dfs(i,0);
}
printf("%d",ans);
return 0;
}