Kruskal(克鲁斯卡尔)

Kruskal算法(一)之 C语言详解
Prim 在稠密图中比 Kruskal 优,在稀疏图中比 Kruskal 劣。
Kruskal:时间复杂度由排序算法决定,若采用快排则时间复杂度为O(N*logN)

例题

Networking

#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int pre[120010];//祖先
struct node{
	int x,y,w;
}t[120010];
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int x)
{
	while(a!=pre[a])
		a=pre[a];
	return a;
}
int merge(int x,int y)//合并
{
	int xx=find(x);
	int yy=find(y);
	if(xx!=yy)
	{
		pre[xx]=yy;
		return 1;
	}else{
		return 0;
	}
} 
int main()
{
	int n,m;
	while(cin>>n,n)
	{
		cin>>m;
		for(int i=0;i<=n;i++)
			pre[i]=i;
		for(int i=0;i<m;i++)
			cin>>t[i].x>>t[i].y>>t[i].w;
		sort(t,t+m,cmp);
		int sum=0,num=0;
		for(int i=0;i<m;i++)
		{
			if(merge(t[i].x,t[i].y))
			{
				sum++;
				num+=t[i].w;
				if(sum==n-1) break;
			}
		}
		cout<<num<<endl;
	}
	return 0;
} 

Building a Space Station

#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
int pre[110];//祖先
//边 
struct node{
	int x,y;
	double w;
}t[120010];
//球的坐标,半径 
struct node2{
	double x,y,z,r;
}ball[200]; 
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int a)
{
	int i=a,j;
	while(a!=pre[a])
		a=pre[a];
	//压缩路径,提高效率
	//并查集中也可以用到
	while(i!=a){
		j=pre[i];
		pre[i]=a;
		i=j;
	}
	return a;
}
int judge(int x,int y)//检查 
{
	int xx=find(x);
	int yy=find(y);
	if(xx!=yy)
	{
		pre[xx]=yy;
		return 1;
	}else{
		return 0;
	}
} 
int init()
{
	for(int i=0;i<=n;i++)
		pre[i]=i;
}
int main()
{
	while(cin>>n,n)
	{
		int num=0;;
		init();
		for(int i=0;i<n;i++)
		{
			cin>>ball[i].x>>ball[i].y>>ball[i].z>>ball[i].r;
			for(int j=0;j<i;j++)
			{
				double s1=(ball[i].x-ball[j].x)*(ball[i].x-ball[j].x);
				double s2=(ball[i].y-ball[j].y)*(ball[i].y-ball[j].y);
				double s3=(ball[i].z-ball[j].z)*(ball[i].z-ball[j].z);
				double R=sqrt(s1+s2+s3)-(ball[i].r+ball[j].r);
				t[num].x=i;
				t[num].y=j;
				t[num++].w=R;
			}
		}
		sort(t,t+num,cmp);
		int numm=0;
		double sum=0;
		for(int i=0;i<num;i++)
		{
			if(judge(t[i].x,t[i].y))
			{
				numm++;
				if(t[i].w>0)
					sum+=t[i].w; 
			}
			if(numm==n-1) break;
		}
		printf("%.3f\n",sum);
	}
	return 0;
} 

Jungle Roads

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=30;
const int M=150;
char c;
int n,num;
int pre[N];
struct node{
	int x,y,w;
}p[M];
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int x)
{
	return x==pre[x]?x:pre[x]=find(pre[x]);
}
void init()
{
	for(int i=0;i<=N;i++)
		pre[i]=i;
}
int kruskal()
{
	int test=1;
	int sum=0;
	for(int i=1;i<num;i++)
	{
		if(test==n) break;
		int xx=find(p[i].x);
		int yy=find(p[i].y);
		if(xx!=yy)
		{
			pre[xx]=yy;
			sum+=p[i].w;
			++test;
		}
	}
	return sum;
}
int main()
{
	while(cin>>n,n)
	{
		num=1;
		init();
		for(int i=1;i<n;i++)
		{
			int a;
			scanf("%c%d",&c,&a);
			cin>>c>>a;
			int use=c-'A';
			for(int j=1;j<=a;j++)
			{
				cin>>c>>p[num].w;//不可直接对 p[num].w 使用 scanf 
				p[num].x=use;
				p[num].y=c-'A';
				num++;
			}
		}
		sort(p+1,p+num,cmp);
		printf("%d\n",kruskal());
	}
	return 0;
}

Constructing Roads

#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <stack>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX=110;
int pre[MAX];
int n;
int test=0;
int num=0;
 
struct node{
	int x,y;
	int w;
}road[40010];
 
bool cmp(node a,node b){
	return a.w<b.w;
}
 
void init(int v){
	for(int i=0;i<=v;i++)
	pre[i]=i;
}
 
int find(int x){
	return x==pre[x]?x:pre[x]=find(pre[x]);
}
bool join(int a,int b){
	int fa=find(a);
	int fb=find(b);
	if(fa!=fb){
		pre[fa]=fb;
		return 1;
	}
	return 0;
}
int kruskal(){
	int sum=0;
	for(int i=1;i<num;i++){
		if(test==n-1)
		break;
		if(join(road[i].x,road[i].y)){
			test++;
			sum+=road[i].w;
		}
	}
	return sum;
}
int main(){
	while(cin>>n){
		init(n);
		num=1;
		test = 0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				cin>>road[num].w;
				road[num].x=i;
				road[num].y=j;
				num++;
			}
		}
		int q;
		cin>>q;
		for(int i=0;i<q;i++){
			int a,b;
			cin>>a>>b;
			if(join(a,b))
			test++;
		}
		sort(road+1,road+num+1,cmp);
			
		cout<< kruskal() <<endl;
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
尔算法是一种用于求解连通网最小生成树的算法,适用于边稀疏的情况。下面是Python实现克尔算法的步骤: 1. 首先,根据给定的图构建一个字典表示的图结构,其中键表示顶点,值表示与该顶点相连的边及其权值。 2. 接下来,将所有的边按照权值大小进行排序。这可以通过定义一个距离列表,将每条边的起始顶点、终止顶点和权值存储在列表中,并使用lambda函数对列表进行排序操作。 3. 初始化一个空的集合用于存储已选择的边,这个集合表示最小生成树。 4. 遍历排序后的边列表,依次检查每条边是否符合以下标准: a. 如果选取这条边会导致形成环路,则舍弃该边。 b. 如果选取这条边不会形成环路,则将该边添加到最小生成树的集合中。 5. 继续遍历,直到最小生成树的边数等于图中顶点数减一,即找到了最小生成树。 下面是Python代码实现克尔算法的示例: ```python def find(parent, i): if parent[i == i: return i return find(parent, parent[i]) def union(parent, rank, x, y): root_x = find(parent, x) root_y = find(parent, y) if rank[root_x < rank[root_y]: parent[root_x = root_y elif rank[root_x > rank[root_y]: parent[root_y = root_x else: parent[root_y = root_x rank[root_x += 1 def kruskal(graph): parent = {} rank = {} result = [] # 初始化parent和rank for v in graph.keys(): parent[v = v rank[v = 0 # 按权值升序遍历边 for u, v, w in graph['distances']: root_u = find(parent, u) root_v = find(parent, v) # 判断是否形成环路 if root_u != root_v: result.append((u, v, w)) union(parent, rank, root_u, root_v) return result ``` 这段代码中,find函数用于查找顶点的根节点,union函数用于合并两个顶点的集合,kruskal函数是主要的算法实现。最终返回的result列表即为最小生成树的边集合。 请注意,上述代码仅为示例,具体的实现可能会根据具体问题而有所调整。同时,还需要根据实际情况定义图的结构和权值的获取方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值