最小生成树--模板

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

输入格式

第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)

接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi

输出格式

输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

 

最小生成树,首先我们要把边从小到大排序,每次添加小的边,即可保证每次添加的边所形成的是最小生成树

这次我们还要用并查集实现 find函数,用来寻找a节点的父亲节点(根节点)

            update把两个节点合并,即根节点相同

1 int find(int x)
2 {
3     if (fa[x]==x) return x;
4     else return fa[x]=find(fa[x]);
5 }
6 int update(int x,int y)
7 {
8     return fa[x] = y;
9 }

 

接下来,我们要判断,每两个节点,是否相连,如果相连,即不用添加边

如果不相连,我们就把小的一个边添加上去

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 int fa[10000];
 6 struct node
 7 {
 8     int st;
 9     int ed;
10     int w;
11 };
12 node a[200000];
13 bool cmp(node a,node b)
14 {
15     return a.w<b.w;
16 }
17 int find(int x)
18 {
19     if (fa[x]==x) return x;
20     else return fa[x]=find(fa[x]);
21 }
22 int update(int x,int y)
23 {
24     return fa[x] = y;
25 }
26 int main()
27 {
28     int n,m;
29     scanf ("%d%d",&n,&m);
30     for (int i = 1;i <= n;i++)
31         fa[i]=i;
32     for (int i = 1;i <= m;i++)
33     {
34         scanf ("%d%d%d",&a[i].st,&a[i].ed,&a[i].w);
35     }
36     int ans=0;
37     int tot=0;
38     sort(a+1,a+m+1,cmp);
39     for (int i = 1;i <= m;i++)
40     {
41         if (find(a[i].st)!=find(a[i].ed))
42         {
43             update(find(a[i].st),find(a[i].ed));
44             ans+=a[i].w;
45             tot++;
46         }
47     }
48     if (tot==n-1)
49     cout<<ans;
50     else 
51     cout<<"orz";
52     return 0;
53 }

现学现卖!

posted @ 2019-10-29 22:50  小又又  阅读(263)  评论(0编辑  收藏  举报