题目:https://www.luogu.org/problemnew/show/P2661
此题表面上是一道求强连通分量的题,实际上很简单无需算法
因为出度为1,所以直接循环就行了。。。
搞了好久恍然大悟
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxSize=200000,maxValue=0x7fffffff;
int n;
int a[maxSize+5],vis[maxSize+5],ru[maxSize+5],dis[maxSize+5],ans;
void dfs1(int x)
{
int i;
printf("%d %d\n",x,dis[x]);
if (vis[a[x]]==1)
{
ans=min(ans,dis[x]-dis[a[x]]+1);
return ;
}
vis[a[x]]=1;
dis[a[x]]=dis[x]+1;
dfs1(a[x]);
dis[a[x]]=0;
}
void dfs(int x)
{
int i;
while (vis[a[x]]==0)
{
vis[a[x]]=1;
dis[a[x]]=dis[x]+1;
x=a[x];
}
ans=min(ans,dis[x]-dis[a[x]]+1);
}
int main()
{
int i,x;
freopen("a.txt","r",stdin);
freopen("b.txt","w",stdout);
scanf("%d",&n);
memset(vis,0,sizeof(vis));
memset(ru,0,sizeof(ru));
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
ru[a[i]]++;
}
for (i=1;i<=n;i++)
{
x=i;
while (ru[x]==0 && vis[x]==0)
{
vis[x]=1;
ru[a[x]]--;
x=a[x];
}
}
ans=maxValue;
for (i=1;i<=n;i++)
if (vis[i]==0)
dfs(i);
printf("%d\n",ans);
return 0;
}