标签: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