镖局运镖-图的最小生成树——Kruskal

镖局运镖-图的最小生成树——Kruskal


最近小哼迷上了《龙门镖局》,从恰克图道武夷山,从张家口道老河口,从迪化道佛山,从蒙自道奉天……古代镖局的运镖,就是运货,也就是现在的物流。镖局每到一个新地方开展业务,都需要对运镖途中的绿林好汉进行大点,好说话的打点费就比较低,不好说话的打点费就比较高。

输入格式:

第一行有两个数n和m,n表示有n个城市(编号从1到n),m表示有m条道路。接下来m行,每行形如“a b c”用来表示一条道路,意思是城市a到城市b连通且打点需要花费的银子数是c。

输出格式:

若通过打点能抵达所有城市,则输出最少需要花费的银子总数。若不能抵达所有的城市则输出“impossible”。

题解:采用Kruskal算法

#include<bits/stdc++.h>
using namespace std;
int n,m,cot,sum;
int f[50];
struct note{
    
    
	int u,v,w;
}e[50];

int getf(int v)
{
    
    
	if(f[v]==v) return f[v];
	return f[v]=getf(f[v]);
}

int merge(int v,int u)
{
    
    
	int t1,t2;
	t1=getf(v);
	t2=getf(u);
	if(t1!=t2){
    
    
		f[t2]=t1;
		return 1;
	}
	return 0;
}
int main()
{
    
    
	cin>>n>>m;
	for(int i=1;i<=m;i++){
    
    
		cin>>e[i].u>>e[i].v>>e[i].w;
	}
	
	for(int i=1;i<=m-1;i++){
    
    
		for(int j=1;j<=m-1;j++){
    
    
			if(e[j].w>e[j+1].w){
    
    
				swap(e[j],e[j+1]);
			}
		}
	}
	
	for(int i=1;i<=n;i++){
    
    
		f[i]=i;
	}
	
	//Kruskal算法核心部分
	for(int i=1;i<=m;i++){
    
    
		if( merge(e[i].u,e[i].v)){
    
    
			cot++;
			sum+=e[i].w;
		}
		if(cot==n-1) break;
	}
	
	cout<<sum<<endl;
/*
	for(int i=1;i<=m;i++){
		cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].w<<endl;
	}
	for(int i=1;i<=n;i++){
		cout<<f[i]<<" ";
	}
*/
	return 0;
}

也可采用Prim算法,时间复杂度为O(n²):再谈最小生成树——Prim

猜你喜欢

转载自blog.csdn.net/qq_45735298/article/details/108766762