D. Shortest Cycle
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given nn integer numbers a1,a2,…,ana1,a2,…,an. Consider graph on nn nodes, in which nodes ii, jj (i≠ji≠j) are connected if and only if, aiaiAND aj≠0aj≠0, where AND denotes the bitwise AND operation.
Find the length of the shortest cycle in this graph or determine that it doesn't have cycles at all.
Input
The first line contains one integer nn (1≤n≤105)(1≤n≤105) — number of numbers.
The second line contains nn integer numbers a1,a2,…,ana1,a2,…,an (0≤ai≤10180≤ai≤1018).
Output
If the graph doesn't have any cycles, output −1−1. Else output the length of the shortest cycle.
Examples
input
Copy
4
3 6 28 9
output
Copy
4
input
Copy
5
5 12 9 16 48
output
Copy
3
input
Copy
4
1 2 4 8
output
Copy
-1
Note
In the first example, the shortest cycle is (9,3,6,28)(9,3,6,28).
In the second example, the shortest cycle is (5,12,9)(5,12,9).
The graph has no cycles in the third example.
弗洛伊德找最短的环,如果不为0的个数比128个多那么就是3。然后就可以暴力了因为数据量控制在很小。为什么是128呢首先数据范围是10^18可以用64位二进制表示而且运算结果不为0表示相同位置为1如果相同位置1的个数大于三那么最短的环肯定就是3,然然后根据 鸽巢原理 64个数(不为0的数但是可以相同)那么每个位置上1的个数至少为1,相同128每个位置上至少2个1如果说超过了128那肯定就是3啦。
枚举每两个本来就可以链接的点然后把它们之间的距离置为正无穷这样就可以用其他的点去更新一个新的“最短路”这样最短路的长度+1就是最短环点的个数。数据范围比较大ll别忘了开。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m,d[300][300],use[200][200];
ll a[200000];
const ll inf=1e10;
int main()
{
int n=0;
cin>>m;
for(int i=1; i<=m; i++)
{
ll x;
cin>>x;
if(x!=0)
a[++n]=x;
}
if(n>120)
cout<<3<<endl;
else if(n<3)
cout<<-1<<endl;
else
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
use[i][j]=(a[i]&a[j]);
}
}
ll ans=inf;
for(int k=1; k<=n; k++)
for(int l=k+1; l<=n; l++)
{
if(use[k][l]==0)
continue;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
d[i][j]=use[i][j]==0?inf:1;
}
d[i][i]=inf;
}
d[k][l]=d[l][k]=inf;
for(int m=1;m<=n;m++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j&&i!=m&&j!=m&&d[i][m]<inf&&d[m][j]<inf)
{
d[i][j]=min(d[i][j],d[i][m]+d[m][j]);
}
}
}
}
ans=min(ans,d[k][l]+1);
}
if(ans<inf)
cout<<ans<<endl;
else
cout<<-1<<endl;
}
}