最小生成樹

就是貪心加上並查集。html

先按邊權從小到大排個序,而後草1到m一條一條加邊,若這條邊相連的兩個節點沒有被連過,就將這兩個點所在的集合合併,這樣直到並查集的樹的邊加到 n - 1 。則最小生成樹各邊長度之和就是並查集各邊長度之和。ios

由於要記錄一條邊鏈接的哪兩個節點,因此開一個結構體,裏面a, b, c表明a和b之間鏈接着一條邊權爲c的邊。ide

上一道例題:https://www.luogu.org/problemnew/show/3366post

代碼spa

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 struct Edge{
 7     int x, y;
 8     ll z;
 9     bool operator < (const Edge& other)const{
10         return z < other.z;
11     };
12 }edge[200005];
13 int p[5005];
14 void init()
15 {
16     for(int i = 1; i <= 5000; ++i) p[i] = i;
17     return;
18 }
19 int Find(int x)
20 {
21     return x == p[x] ? x : p[x] = Find(p[x]);
22 }
23 int merge(int a, int b)
24 {
25     int pa = Find(a), pb = Find(b);
26     if(pa == pb) return 0;
27     else
28     {
29         p[pa] = pb;
30         return 1;
31     }
32 }
33 int main()
34 {
35     init();
36     int n, m, cnt = 0;
37     ll mst = 0;
38     scanf("%d%d", &n, &m);
39     for(int i = 1; i <= m; ++i)
40     {
41         scanf("%d%d%lld", &edge[i].x, &edge[i].y, &edge[i]. z);
42     }
43     sort(edge + 1, edge + m + 1);  //從邊權小的邊開始加
44     for(int i = 1; i <= m; ++i)
45     {
46         if(merge(edge[i].x, edge[i].y) == 1)
47         {
48             cnt++; mst += edge[i].z;
49         }
50         if(cnt == n - 1)
51         {
52             printf("%lld\n", mst);
53             return 0;
54         }
55     }
56     printf("orz\n");
57     return 0;
58 }
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息