题目描述
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入描述
输入数据包括城镇数目正整数N
(≤1000
)和候选道路数目M
(≤3N
);随后的M
行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N
编号。
输出描述
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
思路:
默认先将第一个点加入到集合(开始集合没有数),然后在找到一个其他点到当前集合距离最小的值,将它加入到集合,然后一直循环,再额外处理一点特殊情况即可
代码:
#include <bits/stdc++.h>
using namespace std;
int dis[1005],vis[1005];//dis表示i到整个集合的最小值
int g[1005][1005];
int n,m;
#define INF 0x3f3f3f3f
int prim(){
int res=0;
int t;
memset(dis,INF,sizeof (dis));//将距离默认初始为无穷大
for (int i=0;i<n;i++){
t=-1;
for (int j=1;j<=n;j++){
if (vis[j]==0&&(t==-1||dis[j]<dis[t])){//当j没有被选过,并且(要么轮到这次选时,第一次遇到没被选过的,要么有其他的点到当前集合的值最小)
t=j;
}
}
if (i!=0){
if (dis[t]==INF){
return -1;
}
res+=dis[t];
}
for (int j=1;j<=n;j++){
dis[j]=min(dis[j],g[t][j]);//更新每个值到当前集合的最小值
}
vis[t]=1;//标记
}
return res;
}
int main(){
cin>>n>>m;
int x,y,c;
memset(g,INF,sizeof(g));
while (m--){
cin>>x>>y>>c;
g[x][y]=g[y][x]=min(g[x][y],c);//存双向图,避免有更小值
}
int z=prim();
if (z==-1){
cout<<"-1";
}else{
cout<<z;
}
}