zoukankan      html  css  js  c++  java
  • 最小环-Floyd

    floyd求最小环

    在Floyd的同时,顺便算出最小环。
    Floyd算法
     1 for(k=1;k<=n;k++)
     2   { for(i=1;i<k;i++)
     3      for(j=i+1;j<k;j++)
     4       if(d[i][j]+m[i][k]+m[k][j]<min)
     5        min=d[i][j]+m[i][k]+m[k][j];
     6     for(i=1;i<=n;i++)
     7      for(j=1;j<=n;j++)
     8       if(d[i][k]+d[k][j]<d[i][j])
     9        d[i][j]=d[i][k]+d[k][j];
    10   }

     

    保证了最外层循环到 k 时所有顶点间已求得以 0...k-1 为中间点的最短路径。一
    个环至少有 3 个顶点,设某环编号最大的顶点为 L ,在环中直接与之相连的两个顶点编号
    分别为 M 和 N (M,N < L),则最大编号为 L 的最小环长度即为 Graph(M,L) + Graph(N,L) +
    Dist(M,N) ,其中 Dist(M,N) 表示以 0...L-1 号顶点为中间点时的最短路径,刚好符合 Floyd
    算法最外层循环到 k=L 时的情况,则此时对 M 和 N 循环所有编号小于 L 的顶点组合即
    可找到最大编号为 L 的最小环。再经过最外层 k 的循环,即可找到整个图的最小环。

    上面是对无向图的情况
    若是有向图,只需稍作改动。注意考虑有向图中 2 顶点即可组成环的情况
     
    题目:
    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
    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.

    分析:对于大于2 * 64个正数的情况直接输出3;其余的情况怼入vector跑floyd求最小环。

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int inf = 0x3f3f3f3f;
     5 const int maxn = 1e5 + 10;
     6 vector<ll> vec;
     7 ll g[210][210];
     8 ll dis[210][210];
     9 int num;
    10 
    11 int floyd()
    12 {
    13     ll res = 1e9;
    14     for (int i = 1; i <= num; i++)
    15         for (int j = 1; j <= num; j++)
    16             dis[i][j] = g[i][j];
    17     for (int k = 1; k <= num; k++)
    18     {
    19         for (int i = 1; i < k; i++)
    20             for (int j = i + 1; j < k; j++)
    21                 res = min(res, dis[i][j] + g[i][k] + g[k][j]);
    22         for (int i = 1; i <= num; i++)
    23             for (int j = 1; j <= num; j++)
    24                 dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
    25     }
    26     return res != 1e9 ? res : -1;
    27 }
    28 
    29 int main()
    30 {
    31     int n; cin >> n;
    32     int cnt = 0;
    33     ll x;
    34 
    35     for (int i = 1; i <= n; i++)
    36     {
    37         scanf("%lld", &x);
    38         if (x > 0) cnt++, vec.push_back(x);
    39     }
    40     if (cnt >= 200)
    41     {
    42         cout << "3" << endl;
    43         return 0;
    44     }
    45     num = vec.size();
    46     for (int i = 0; i < num; i++)
    47         for (int j = i + 1; j < num; j++)
    48             g[i + 1][j + 1] = g[j + 1][i + 1] = (vec[i] & vec[j]) ? 1 : inf;
    49     cout << floyd() << endl;
    50 }

     

     

     

  • 相关阅读:
    php基本语法与安装
    面向对象编程 es5和es6的构造函数
    利用正则搜索替换
    正则特殊符号
    正则边界符 限定符
    面试官给我挖坑:rm删除文件之后,空间就被释放了吗?
    为什么 IPv6 难以取代 IPv4
    Docker系列教程04-Docker构建镜像的三种方式
    Docker系列教程03-Docker私有仓库搭建(registry)
    Linux-I/O模型详解
  • 原文地址:https://www.cnblogs.com/liuwenhan/p/11376160.html
Copyright © 2011-2022 走看看