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 }

     

     

     

  • 相关阅读:
    反射(8)程序集反射 Type 类
    反射(5)CLR 运行时探测程序集引用的步骤
    反射(1)程序集基础知识
    csc.exe(C# 编译器)
    证书(1)数字签名基础知识
    反射(7)动态程序集加载Load方法
    SignTool.exe(签名工具)
    反射(3)程序集加载 Assembly类
    关于卡巴斯基安全免疫区随笔
    文本提取工具 TextHelper
  • 原文地址:https://www.cnblogs.com/liuwenhan/p/11376160.html
Copyright © 2011-2022 走看看