CodeForces - 742C Arpa's loud Owf and Mehrdad's evil pla
题意:问题可转化为 给定一个有向图,相邻两点的距离是1,求一个最小的 t,使从任意一点x走k步到y,y也能走k步到x,t不存在则输出-1
思路:有向图找环问题,如果存在 t,则有向图肯定由若干个环组成,如果环的长度k为奇数,那么需要k步,如果环的长度为偶数,那么需要可k/2步,如:1->2->3->4->5->6->1 环的长度为6,可以从1走3步到4,在从4走3步到1,然后求所有k的最小公倍数,注意会超int范围
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
int a[101],vis[101];
ll res[101];
ll gcd(ll a, ll b){
if(b==0) return a;
return gcd(b, a%b);
}
int dfs(int u,int st,int l)
{
vis[u]=1;
if(a[u]==st) return l+1;
else if(vis[a[u]]) return -1;
return dfs(a[u],st,l+1);
}
int main(void)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int can=1,j=0;
for(int i=1;i<=n;i++){
if(vis[i]) continue;
int temp=dfs(i,i,0);
if(temp==-1){
can=0;
break;
}
else res[j++]=temp%2==0?temp/=2:temp;
}
if(!can)
printf("-1\n");
else{
ll lcm,c=res[0],e;
for(int i=0;i<j;i++){
e=gcd(c,res[i]);
lcm=c*res[i]/e;
c=lcm;
}
printf("%lld\n",lcm);
}
return 0;
}