#include <bits/stdc++.h>
#define INF 0x3f3f3f3f //INF>10^9
#define N 1100
using namespace std;
int mp[N][N]; //邻接矩阵存储图
int dis[N]; //标记数组
int vis[N]; //用来记录当前生成树到每个节点的距离
int sum, n, m;//n代表节点数 sum保存生成树的权值总和
void prim()
{
sum=0; //最小生成树的权值总和初始化为0
int mm;
memset(vis, false, sizeof(vis)); //初始化节点均没有被访问
for(int i = 1; i <= n; i++)
{
dis[i] = mp[1][i]; //我们从0号节点开始生成树
}
vis[1] = true; //生成树的根(起点)标记访问
int pos; //用来记录每一次循环找到的节点的编号
int d = 0; //标记变量
for(int i = 1; i < n; i++) //要生成n-1条边,所以循环n-1次
{
mm = INF;
for(int j = 1; j <= n; j++) //对dis数组进行遍历,找到值最小的
{
if(!vis[j] && dis[j] < mm)
{
mm = dis[j];
pos = j;
}
}
if(mm == INF) //如果在此跳出循环,表示有城市之间不能连通
{
d = 1;
break;
}
sum += mm; //加上找到的最小权值
vis[pos] = true; //标记找到的该节点被访问
for(int j = 1; j <= n; j++) //更新dis数组
{
if(!vis[j] && dis[j] > mp[pos][j])
{
dis[j] = mp[pos][j]; //如果该点还没有被访问过,
//更新生成树到该点的距离;
}
}
}
if(d == 0)
printf("%d\n", sum); //n-1次循环完毕后输出权值总和
else
printf("-1\n");
}
int main()
{
while(cin >> n >> m)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++) //对mp数组初始化
{
if(i == j)
mp[i][j] = 0;
else
mp[i][j] = INF;
}
}
while(m--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(mp[a][b] > c) //如果存在重边,取最小值
mp[a][b] = mp[b][a] = c;
}
prim(); //执行普利姆算法
}
return 0;
}
数据结构实验之图论六:村村通公路
最新推荐文章于 2020-11-25 15:47:39 发布