P3366 模板最小生成树(kruskal算法)
Posted liuzhaojun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3366 模板最小生成树(kruskal算法)相关的知识,希望对你有一定的参考价值。
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz
输入格式
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
输入输出样例
输入 #1
4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 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
#include<iostream> #include<algorithm> using namespace std; const int inf=200000; struct node int u,v,w; ; struct node e[inf]; int n,m,f[inf],sum=0,cnt=0; bool cmp(node t1,node t2) return t1.w<t2.w; int find(int x) if(x!=f[x]) return f[x]=find(f[x]); else return x; int merge(int x,int y) int x1=find(x); int y1=find(y); if(x1!=y1) f[y1]=x1; return 1; return 0; int main() int t1,t2; cin>>n>>m; for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].w; merge(e[i].u,e[i].v); cnt=0; for(int i=1;i<=n;i++) if(f[i]==i) cnt++; if(cnt!=1) cout<<cnt<<endl; cout<<"orz"<<endl; return 0; for(int i=1;i<=m;i++) f[i]=i; cnt=0; sort(e+1,e+m,cmp); for(int i=1;i<=m;i++) if(merge(e[i].u,e[i].v)) cnt++; sum=sum+e[i].w; if(cnt==n-1) break; cout<<sum<<endl; return 0;
从边开始找
first 给所有的边从小到大排序
找的边要满足这样的条件 边的两点属于不同的连通分量(使用并查集)
找到n-1条边就行了
这就是克鲁斯卡尔算法
以上是关于P3366 模板最小生成树(kruskal算法)的主要内容,如果未能解决你的问题,请参考以下文章
P3366 模板最小生成树 (贪心+并查集,kruskal)