标签:log 返回 blog stl 连通 har sharp oid 自定义
Kruskal算法是生成最小生成树的一种好的算法,巧妙地运用了并查集。
#include<cstdio>
#include<algorithm> //调用STL库,使用sort排序
using namespace std;
struct s {int u;int v;int w;}; //定义结构体,用于储存边的起点,终点和权值
int N,M,ml,fa[5005]; //定义点数,边数,最小生成树的权值和,并查集代表元素
s e[200005]; //定义边集
bool cmp(s a,s b) {return a.w<b.w;} //自定义比较函数,将边按权值排序
int f(int i) { //定义函数用于查询是否同属于同一集合
if(fa[i]==i) return i; //如果本元素指向的元素是其本身,说明该元素为集合的代表元素,则返回
else return fa[i]=f(fa[i]); //否则更新元素指向的元素,使其直接指向集合的代表元素
}
void to_small() { //定义函数用于生成最小生成树
sort(e,e+M,cmp); //按权值排序边
for(int t=1;t<=N;++t) fa[t]=t; //初始化并查集,使元素指向本身
for(int t=1;t<=M;++t) { //遍历每一条边
if(f(e[t].u)!=f(e[t].v)) { //如果边的起点和终点不属于同一集合
ml+=e[t].w; //将该边加入最小生成树
fa[f(e[t].u)]=fa[f(e[t].v)]; //让边的起点和终点处于同一集合
}
}
printf("%d",ml); //输出最小权值和
}
int main() {
scanf("%d%d",&N,&M); //读入点数,边数
for(int t=1;t<=M;++t) scanf("%d%d%d",&e[t].u,&e[t].v,&e[t].w); //读入每条边的起点,终点,权值
if(M<N-1) printf("orz"); //如果图不连通,输出org
else to_small(); //如果图连通,则生成最小生成树
return 0;
}
标签:log 返回 blog stl 连通 har sharp oid 自定义
原文地址:http://www.cnblogs.com/Mr94Kevin/p/7413499.html