首页 > 代码库 > 库鲁斯卡尔算法

库鲁斯卡尔算法

//Kruskal 算法的实现#include <iostream>#include <string>#include <iomanip>#include <cctype>#include <cstdio>#include <cstring>#include <algorithm>using namespace std; struct node{	int u;	int v;	int w;};int father[101];int son[101];int cmp(node a, node b){    return a.w<b.w;}int find(int x){	return x==father[x]? x : find(father[x]);}bool join(int x, int y) //加入者两个点连成的边 会怎样?{    int xx=find(x);	int yy=find(y);	if(xx==yy)		return false; //加入此边 将构成环路  返回false	else if( son[xx]>=son[yy] )	{        father[yy] = xx;		son[xx] = son[xx]+son[yy];	}	else	{		father[xx]=yy;		son[yy] = son[yy]+son[xx];	}    return true;}int main(){	int n, m;	int i, j;    int cnt;	int sum;    node edge[1000];	while(cin>>n>>m)	{		if(m==0)		{			cout<<"0\n";			continue;		}		for(i=0; i<m; i++)		{			cin>>edge[i].u>>edge[i].v>>edge[i].w;		}        sort(edge, edge+1, cmp );		for(j=0; j<=n; j++)		{			father[j]=j;			son[j]=j;		}		cnt=0;		sum=0;		int flag=0;		for(i=0; i<m; i++)		{				if(join(edge[i].u, edge[i].v))			{				cnt++;				sum+=edge[i].w;			}			if(cnt==m-1)			{				flag=1;				break;			}		}		if(flag)		{			cout<<sum<<endl;		}	}	return 0;}//////////////////////////////////*#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>using namespace std;#define MAX 1000int father[MAX], son[MAX];int v, l;typedef struct Kruskal //存储边的信息 这样的话结构体根据边值 排序{ 	int a;	int b;	int value;};bool cmp(const Kruskal & a, const Kruskal & b){	return a.value < b.value;}int unionsearch(int x) //查找根结点+路径压缩{	return x == father[x] ? x : unionsearch(father[x]);}bool join(int x, int y) //合并{	int root1, root2;	root1 = unionsearch(x);	root2 = unionsearch(y);	if(root1 == root2) //为环		return false;	else if(son[root1] >= son[root2])		{			father[root2] = root1;			son[root1] += son[root2];		}		else		{			father[root1] = root2;			son[root2] += son[root1];		}	return true;}int main(){	int ncase, ltotal, sum, flag;	Kruskal edge[MAX];	scanf("%d", &ncase);	while(ncase--)	{		scanf("%d %d", &v, &l); //v个顶点 l条边		ltotal = 0, sum = 0, flag = 0;		for(int i = 1; i <= v; ++i) //初始化 并查集数组初始化		{			father[i] = i;			son[i] = 1;		}		for(int i = 1; i <= l ; ++i) //读入点 边 权,存入结构体,等待排序		{			scanf("%d %d %d", &edge[i].a, &edge[i].b, &edge[i].value);		}		sort(edge + 1, edge + 1 + l, cmp); //按权值由小到大排序		for(int i = 1; i <= l; ++i) //循环 这l条边(注意已排好序 从权值最小的边开始 )		{			if(join(edge[i].a, edge[i].b) ) //如果加入该条边是合法的			{				ltotal++; //边数加1				sum += edge[i].value; //记录权值之和				cout<<edge[i].a<<"->"<<edge[i].b<<endl;			}			if(ltotal == v - 1) //最小生成树条件:边数=顶点数-1 边的总数可能很多,当已经加入n-1条边后就可以直接跳出了			{				flag = 1;				break;			}		}		if(flag) 			printf("%d\n", sum);		else 			printf("data error.\n");	}	return 0;}  */

  

库鲁斯卡尔算法