思路:n大于某个值肯定有个三元环,否则floyd找最小环。
代码:
#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC optimize(4)#include using namespace std;#define double long double#define y1 y11#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb emplace_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair #define pli pair #define pii pair #define piii pair #define pdd pair #define mem(a, b) memset(a, b, sizeof(a))#define debug(x) cerr << #x << " = " << x << "\n";#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//head const int N = 1e5 + 5;const int INF = 1e8;LL a[N];int mp[205][205], dis[205][205];int n, cnt;int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]), cnt += a[i]==0; sort(a+1, a+1+n, greater ()); n -= cnt; if(n >= 200) { printf("3\n"); return 0; } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if(i == j) continue; if(((a[i]&a[j]) != 0)) mp[i][j] = dis[i][j] = 1; else mp[i][j] = dis[i][j] = INF; } } int ans = INF; for (int k = 1; k <= n; ++k) { for (int i = 1; i < k; ++i) { for(int j = i+1; j < k; ++j) { ans = min(ans, dis[i][j]+mp[j][k]+mp[k][i]); } } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]); } } } if(ans == INF) printf("-1"); else printf("%d\n", ans); return 0;}