[CF1205B] Shortest Cycle

(n(nleq 10^5)) 个数 (a_1,...,a_n (aleq 10^{18})) 。有一个图用这个方法生成,若 (a_i) 按位与 (a_j) 不为 (0),则在 (a_i,a_j) 间连一条无向边。求这个图的最小环,若无环输出 (-1)

Solution

(a_i=0) 的数字删掉

(n ge 128) 时,至少有一个二进制位满足该位为 (1) 的数个数 (ge 3),即形成三元环

(n<128) 时,暴力建图后用 Floyd 跑最小环即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 205;

int n,a[N],g[N][N],f[N][N];

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) {
        if(i>128) break;
        cin>>a[i];
        if(a[i]==0) --i, --n;
    }
    if(n>=128) {
        cout<<3;
        return 0;
    }
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            if(i==j) f[i][j]=g[i][j]=0;
            else f[i][j]=g[i][j]=(a[i]&a[j]?1:999);
        }
    }
    int ans=999;
    for(int k=1;k<=n;k++) {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) if(i!=j&&j!=k&&i!=k) {
                ans=min(ans,f[i][k]+f[k][j]+g[j][i]);
            }
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
                if(g[i][k]+g[k][j] < g[i][j]) {
                    g[i][j]=g[i][k]+g[k][j];
                }
            }
        }
    }

    cout<<(ans>=999?-1:ans)<<endl;
}

原文地址:https://www.cnblogs.com/mollnn/p/12572168.html