题目描述如下:
有一张城市地图,图中的顶点为城市,编号为 1∼n,无向边 代表两个城市间的连通关系,边上的权值为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任何一对城市都是连通的。
现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
输入格式:
第一行包含两个整数 n 和 e,分别表示城市个数和无向边个数。
接下来 e 行,每行包含三个整数 i,j,w,表示在城市 i 和城市 j 之间修建公路的造价为 w。
城市编号从 1 开始。
输出格式
共 n−1 行,每行为两个城市的编号,表明在这两个城市间建一条高速公路。
本题答案不一定唯一,输出任意一种最优方案即可,方案中边和点的顺序可以任意选择。
数据范围
1≤n≤100,
1≤e≤1000,
1≤w≤10000
数据保证不含重边和自环。
输入样例:
5 8
1 2 2
2 5 9
5 4 7
4 1 10
1 3 12
4 3 6
5 3 3
2 3 8
输出样例:
1 2
2 3
3 4
3 5
问题分析如下:
该问题是一个典型的用最小生成树求解的题目,可使用Kruskal算法求解。
注意:
区分清楚集合的连线和边的连线。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct Edge{
int start;
int end;
int weight;
}a[1005];
bool cmp(Edge a,Edge b){
if(a.weight==b.weight)
return a.end<b.end;
return a.weight<b.weight;
}
int v[105];
int find_father(int x){
if(x!=v[x]){
int y=find_father(v[x]);
return y;
}
return x;
}
int main()
{
int n,e;
cin>>n>>e;
for(int i=1;i<=n;i++)
v[i]=i;
for(int i=0;i<e;i++)
{
cin>>a[i].start>>a[i].end>>a[i].weight;
}
sort(a,a+e,cmp);
int count=0;
for(int j=0;j<e;j++)
{
int fx=find_father(a[j].start);
int fy=find_father(a[j].end);
if(fx!=fy){
cout<<a[j].start<<" "<<a[j].end<<endl;
v[fx]=fy;
count++;
}
if(count==n-1)
break;
}
return 0;
}