题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出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 }
现学现卖!