最小生成树两种常用算法

最小生成树的简易实现

一:Kruskal 算法
①算法核心思想:
Kruskal是实现最小生成树比较简单的一种算法。该算法主要是应用了并查集的思想,先对图各边进行按权值从小到大排序,再孤立各个点,然后按序遍历各边将在集合外的点并到集合里,形成一个最小生成树复杂度最少为O(nlogn)。
②例题P2504聪明的猴子
AC代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
    
    
	int x,y;
	int len;
}w[1000009];
int pre[1000009];
int bloon[1000009];
int wood[1000009][3];

int find(int x){
    
    
	if(x==pre[x]){
    
    
		return x;
	}
	return pre[x]=find(pre[x]);//路径压缩算法
}

int cmp(node a,node b){
    
    
	return a.len<b.len;
}

int main(){
    
    
	int n;
	cin>>n;
	for(int i=1;i<=n;++i){
    
    
		cin>>bloon[i];
	}
	int m;
	cin>>m;
	for(int i=1;i<=m;++i){
    
    
		cin>>wood[i][1]>>wood[i][2];
	}
	int k=0;	
	for(int i=1;i<=m;++i){
    
    
		for(int j=1;j<=m;++j){
    
    
			if(i!=j){
    
    
				w[++k].x=i;
				w[k].y=j;
				w[k].len=sqrt((wood[i][1]-wood[j][1])*(wood[i][1]-wood[j][1])+(wood[i][2]-wood[j][2])*(wood[i][2]-wood[j][2]));
			}
		}
	}	
	for(int i=1;i<=m;++i){
    
    
		pre[i]=i;//孤立各点
	}	
	sort(w+1,w+k+1,cmp);//自定义一个cmp排序函数	
	int length;
	int cnt=m;
	for(int i=1;i<=k;++i){
    
    
		if(cnt==1)break;
		int s1=find(w[i].x);int s2=find(w[i].y);
		if(s1!=s2){
    
    
			cnt--;
			pre[s1]=s2;
			length=w[i].len;
		}
	}
	int ans=0;
	for(int i=1;i<=n;++i){
    
    
		if(bloon[i]>=length)ans++;
	}
	cout<<ans<<endl;
	return 0;
}

二:Prim算法
①算法核心思想:
个人认为Prim算法会对初学者更友好一点,因为它是直接并和各点。首先把各点的距离设为无限大,把各点标记为零,然后遍历各点,找到与标记为一的点距离最近的点,然后更新该点标记为一,把其他“零点”到“一点”的距离更新为最短距离,算法复杂度O(n^2+m)。
②例题#2419繁忙的都市
AC代码:

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

int st[1009][1009];

int main()
{
    
    
	int n,m;
	cin>>m>>n;
	int x,y;
	for(int i=1;i<=n;++i){
    
    
		cin>>x>>y;
		cin>>st[x][y];
		st[y][x]=st[x][y];
	}
	int p[1009]={
    
    0};
	int v[1009];
	memset(v,0x7f,sizeof(v));
	v[1]=0;
	int maxv=0;
	for(int i=1;i<=m;++i){
    
    
		int k=0;
		int j;
		for(j=1;j<=m;++j){
    
    
			if(!p[j]&&v[k]>v[j])k=j;
		}
		p[k]=1;
		maxv=max(maxv,v[k]);
		for(j=1;j<=m;++j){
    
    
			if(!p[j]&&st[j][k]<v[j]&&st[j][k]!=0)v[j]=st[j][k];
		}		
	}
	cout<<m-1<<" "<<maxv<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/skl4869/article/details/116664953