最小环-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 }

 

 

 

posted @ 2019-08-19 11:33  滚烫的青春  阅读(274)  评论(0编辑  收藏  举报