Kruskal板子

Kruskal和prim不同的点在于prim每次都是找离集合距离最小的点,Kruskal找的是图中最短的边,如果边的两端不连通,则加入生成树中,属于是贪心的策略。

思路:

①每次都找最短的边,因此首先对所有的边进行从小到大的排序,因为排序,所以Kruskal的时间复杂度下限就已经是O(nlogn)了;

②判断两个点连不连通,直接使用并查集就可以了。

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int N = 2e5 + 9;
 6 int n,m,p[N],res,cnt;
 7 struct Edge
 8 {
 9     int a,b,w;
10     bool operator <(const Edge& W)
11     {
12         return w < W.w;
13     }
14 }edges[N];
15 
16 int find(int x)
17 {
18     if(p[x] != x)
19         p[x] = find(p[x]);
20     return p[x];
21 }
22 
23 int main()
24 {
25     cin >> n >> m;
26     for(int i = 0;i < m;++i)
27     {
28         int a,b,c;
29         cin >> a >> b >> c;
30         edges[i] = {a,b,c};
31     }
32     
33     for(int i = 1;i <= n;++i)
34         p[i] = i;
35     
36     sort(edges,edges + m);
37     
38     for(int i = 0;i < m;++i)
39     {
40         int a = edges[i].a,b = edges[i].b,w = edges[i].w;
41         int pa = find(a),pb = find(b);
42         if(pa != pb)
43         {
44             ++cnt;
45             res += w;
46             p[pa] = pb;
47         }
48     }
49     if(cnt < n - 1)
50         cout << "impossible" << endl;
51     else
52         cout << res << endl;
53     return 0;
54 }

 

上一篇:Springboot使用@Autowired注解静态对象


下一篇:最小生成树详解