转自
http://www.cnblogs.com/cangT-Tlan/p/7794372.html
自己加了点注释,很有用的模板
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz
输入输出格式
输入格式:
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
输入输出样例
说明
时空限制: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
ac代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 200010
using namespace std;
int n,m,tot,sum;
int fa[MAXN];
struct nond{
int x,y,z;
}edge[MAXN];
int cmp(nond a,nond b){
return a.z<b.z;
}
int find(int x){
if(fa[x]==x) return fa[x];
else return fa[x]=find(fa[x]);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);
//排序从最小的权开始生成树 并且保证之后加入的节点都是从小到大的
sort(edge+1,edge+1+m,cmp);
for(int i=1;i<=m;i++){
int dx=find(edge[i].x);
int dy=find(edge[i].y);
//判断是否联通 如果不联通的话将其加入并计算权值
if(dx==dy) continue;
fa[dy]=dx;
sum+=edge[i].z;
tot++;
if(tot==n-1) break;
}
cout<<sum;
}