zoukankan      html  css  js  c++  java
  • D. Shortest Cycle(floyd最小环)

    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 (iji≠j) are connected if and only if, aiaiAND aj0aj≠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 n(1n105)(1≤n≤105) — number of numbers.

    The second line contains nn integer numbers a1,a2,,ana1,a2,…,an (0ai10180≤ai≤1018).

    Output

    If the graph doesn't have any cycles, output 1−1. Else output the length of the shortest cycle.

    Examples
    input
    4
    3 6 28 9
    
    output
    4
    input
    5
    5 12 9 16 48
    
    output
    3
    input
    4
    1 2 4 8
    
    output
    -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.

    算法:floyd最小环

    题解:根据题意建图,跑最小环模板。

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    #define INF 0x3f3f3f3f
    const int maxn = 1e5+7;
    
    typedef long long ll;
    
    int n;
    ll arr[maxn];
    ll dis[200][200];
    ll maze[200][200];
    
    int floyd() {
        ll res = INF;
        for(int k = 1; k <= n; k++) {
            //下面两个循环先算res的原因是:你从i~j的最短路还没有经过k
            //其实就是我先不管i~k,k~i这条边(等同于删除),然后找到i~j这条边的权值,再加上i~k,k~j这条边就是一个环了,找到最小的情况
            for(int i = 1; i < k; i++) {    
                for(int j = i + 1; j < k; j++) {
                    res = min(res, dis[i][j] + maze[i][k] + maze[k][j]);
                }
            }
            //这个循环就是floyd更新多源最短路
            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]);
                }
            }
        }
        return res;
    }
    
    int main() {
        scanf("%d", &n);
        int k = 0;
        for(int i = 1; i <= n; i++) {
            ll x;
            scanf("%I64d", &x);
            if(x != 0) {    //将0去掉,0按位与任何数就是0,不存在有这种情况的环
                arr[++k] = x;
            }
        }
        n = k;
        if(n > 3 * 64) {    //因为每位数最多64位,因为没有0,所以这64位上,必定有有一位有值,当同一位的值超过3时,最小环就由这三个数组成
            printf("3
    ");
            return 0;
        }
        //建图
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(arr[i] & arr[j]) {
                    dis[i][j] = dis[j][i] = maze[i][j] = maze[j][i] = 1;
                } else {
                    dis[i][j] = dis[j][i] = maze[i][j] = maze[j][i] = INF;
                }
            }
        }
        int ans = floyd();
        if(ans == INF) {    //没有形成环
            printf("-1
    ");
        } else {
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Vue-router 路由
    第一个Vue-cli
    webpack学习
    kail拦截自己局域网
    kaii在普通用户进入root的时候,使用''su '',出现鉴定故障
    Kali Linux缺少ifconfig命令
    SpringIOC
    JavaScript图形实例:太极图
    JavaScript图形实例:玩转正方形
    JavaScript图形实例:模仿海龟作图
  • 原文地址:https://www.cnblogs.com/buhuiflydepig/p/11375682.html
Copyright © 2011-2022 走看看