描述
有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
格式
输入格式:
n(城市数,1<≤n≤100)e(边数)以下e行,每行3个数i,j,wij(wij≤3000),表示在城市i,j之间修建高速公路的造价。
输出格式:
一个整型数,表示得到的最小工程造价。
样例
输入样例:
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
输出样例:
19
代码
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
struct road{
int s;
int e;
int lenth;
};
road edge[5000];
int n,m;
int father[5000];
int maxn=0;
int find(int x)
{
if(x!=father[x])
return find(father[x]);
else
return x;
}
bool compare(road a,road b)
{
return a.lenth<b.lenth;
}
int kruskal()
{
int ans=0,num_edge=0;
//ans为所求最小生成树的边权之和,num_edge为当前生成树的边数
for(int i=0;i<n;i++)//father[]初始化
father[i]=i;
sort(edge,edge+m,compare);//注意sort是从0开始的
for(int i=0;i<m;i++)
{
int ns=find(edge[i].s);
int ne=find(edge[i].e);
if(ns!=ne)//如果两个节点的父亲节点不同,则将次边加入最小生成树
{
ans+=edge[i].lenth;//加上边权
father[ns]=ne;
num_edge++;
if(num_edge==n-1)//如果最小生成树的边数目达到节点数减一,就退出
break;
}
}
return ans;
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int u,v,c;
cin>>u>>v>>c;
edge[i].s=u;
edge[i].e=v;
edge[i].lenth=c;
}
int rel=kruskal();
cout<<rel<<endl;
return 0;
}