【题目描述】
有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
【输入】
n(城市数,1<≤n≤100)
e(边数)
以下e行,每行3个数i,j,wiji,j,wij,表示在城市i,j之间修建高速公路的造价。
【输出】
n-1行,每行为两个城市的序号,表明这两个城市间建一条高速公路。
【输入样例】
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
代码里面的注释比较完整了
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int MAXN=105;//最大点数
const int MAXM=10000;//最大边数
int F[MAXN];//并查集使用
int tol;//边数,加边前赋值为0
struct Edge
{
int u,v,w;
}edge[MAXM];//储存边的信息,包括起点/终点/权值
void addedge(int u,int v,int w)
{
edge[tol].u=u;
edge[tol].v=v;
edge[tol++].w=w;
}
bool cmp(Edge a,Edge b)//排序函数,边按照权值从小到大排序
{
return a.w<b.w;
}
int Find(int x)
{
if(F[x]==-1)
return x;
else
return F[x]=Find(F[x]);
}
int Kruskal(int n)//传入点数,返回最小生成树的权值,如果不连通返回-1
{
memset(F,-1,sizeof(F));
sort(edge,edge+tol,cmp);
int cnt=0;//计算加入的边数
int ans=0;//权值的和
for(int i=0;i<tol;i++)
{
int u=edge[i].u;
int v=edge[i].v;
int w=edge[i].w;
int t1=Find(u);
int t2=Find(v);
if(t1!=t2)
{
ans+=w;
F[t1]=t2;
cout<<u<<" "<<v<<endl;
cnt++;
}
if(cnt==n-1)
break;
}
if(cnt<n-1)
return -1;//不连通
else
return ans;
}
int main()
{
int n,m;
cin>>n>>m;
tol=0;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
addedge(a,b,c);
}
Kruskal(n);
return 0;
}