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