首页 > 代码库 > P3366 【模板】最小生成树

P3366 【模板】最小生成树

题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1:
4 51 2 21 3 21 4 32 3 43 4 3
输出样例#1:
7

说明

时空限制:1000ms,128M

数据规模:

对于20%的数据:N<=5,M<=20

对于40%的数据:N<=50,M<=2500

对于70%的数据:N<=500,M<=10000

对于100%的数据:N<=5000,M<=200000

样例解释:

技术分享

所以最小生成树的总边权为2+2+3=7

 

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=200001; 7 struct node 8 { 9     int u,v,w;10 }edge[MAXN];11 int f[MAXN];12 int comp(const node & a,const node & b)13 {14     return a.w<b.w;15 }16 int find(int x)17 {18     if(f[x]!=x)19     f[x]=find(f[x]);20     return f[x];21 }22 void unionn(int x,int y)23 {24     int fx=find(x);25     int fy=find(y);26     f[fx]=fy;27 }28 int main()29 {30     int n,m;31     scanf("%d%d",&n,&m);32     for(int i=1;i<=n;i++)33     f[i]=i;34     for(int i=1;i<=m;i++)35     {36         scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);37     }38     sort(edge+1,edge+m+1,comp);39     int k=0;40     int ans=0;41     for(int i=1;i<=m;i++)42     {43         if(find(edge[i].u)!=find(edge[i].v))44         {45             unionn(edge[i].u,edge[i].v);46             ans+=edge[i].w;47             k++;48         }49         if(k==n-1)break;50     }51     if(k!=n-1)52     printf("orz");53     else printf("%d",ans);54     return 0;55 } 

 

P3366 【模板】最小生成树