题目:Shortest Cycle
题目链接:https://vjudge.net/contest/351234#problem/D
题目描述:给图判断有无环并找最小环。
题目反思:
1.咋看,这图实在太大了,什么方法都肯定超时,当非0点数达到64必定成环,达到128最小环必定为3(因为当同一连结点的数达到3,最小环必定为3).所以把非零点数大于128排除即可。
2.题目给出的信息相对较小,所以要自己挖掘信息,而且避免主观意想。笔者一直认为给出的数是不重复的,结果没有重视0的节点,要把128以上的图排除,前提是没有0的干扰。
3.这里用Floyd解决最小环问题
代码:
#include <stdio.h>
#include <stdlib.h>
int a[205][205];
unsigned long long b[100005];
int c[205][205];
int n,ans=1e8;//无限不能开太大小心运算时爆掉
int min(int x,int y) //简化比较大小写法
{
return x<y?x:y;
}
void floyd() //求最小环
{
int i,j,k;
for(k=0;k<n;k++)
{
for(i=0;i<k;i++)
for(j=i+1;j<k;j++)
ans=min(ans,a[i][j]+c[i][k]+c[k][j]);//更新环
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);//更新两点最短路
}
}
int main()
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lld",b+i);
if(b[i]==0) {n--;i--;} //筛0
}
if(n>=200) {printf("3\n");return 0;}//排除点过多的情况
for(i=0;i<n;i++)//初始化
{
for(j=0;j<n;j++)
{
if(b[i]&b[j]) {a[i][j]=c[i][j]=1;}
else {a[i][j]=c[i][j]=1e8;}
}
}
for(i=0;i<n;i++) a[i][i]=c[i][i]=0;
floyd();
if(ans==1e8) printf("-1\n");
else printf("%d\n",ans);
return 0;
}