传送门:http://codeforces.com/contest/1205/problem/B
由于是 & 不为0就能连边,那么我们考虑每个数字的二进制的1-62位,如果另外一个数字在这一位上也有,那么他们就有一条边相连。
而且我们知道,如果某一位上有3个数字都有这位,那么答案就是3了,那么总大于0的数字个数不超过124,否则直接ans=3.
然后对124个数字建图,求最小环大小就用floyed。
#include<bits/stdc++.h>
#define maxl 100010
using namespace std;
int n,nn,ans=maxl,tot;
long long a[maxl];
int cnt[64];
int num[64][3];
int f[204][204],w[204][204];
inline void prework()
{
for(int i=1;i<=140;i++)
for(int j=1;j<=140;j++)
f[i][j]=w[i][j]=maxl;
scanf("%d",&nn);n=0;
long long x;
for(int i=1;i<=nn;i++)
{
scanf("%lld",&x);
if(x>0)
a[++n]=x;
}
if(n>128)
{
ans=3;
return;
}
int id1,id2;
for(int i=0;i<63;i++)
for(int j=1;j<=n;j++)
if((a[j]>>i)&1)
for(int k=j+1;k<=n;k++)
if((a[k]>>i)&1)
{
f[k][j]=f[j][k]=1;
w[k][j]=w[j][k]=1;
}
}
inline void mainwork()
{
if(ans<maxl)
return;
n=128;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
if(i!=k)
for(int j=1;j<=n;j++)
if(i!=j && k!=j)
{
ans=min(ans,w[k][j]+w[i][k]+f[i][j]);
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
inline void print()
{
if(ans<maxl)
printf("%d",ans);
else
puts("-1");
}
int main()
{
prework();
mainwork();
print();
return 0;
}