/*普里姆算法,Prim
**最小生成树,n个顶点,用n-1条边把一个连通图链接起来,并且使得权值的和最小。
我们把构造连通网的最小代价生成树称为最小生成树。
*/
#include<stdio.h>
#define DEBUG_IO (0)
const int MAX = 201;
const int INF = 65535;
int main()
{
#if DEBUG_IO
freopen("input.txt", "r", stdin);
setbuf(stdout, NULL);
#endif
int i, j, k, x, y, v;
int answer;
int V;
int E;
scanf("%d %d", &V, &E);
int vis[MAX] = {0};
int low[MAX] = {0};
int map[MAX][MAX] = {0};
for(i = 1; i <= V; i++)
{
for(j = 1; j <= V; j++)
{
map[i][j] = INF;
}
}
//把输入转换为邻接矩阵
for(i = 0; i < E; i++)
{
scanf("%d %d %d", &x, &y, &v);
map[x][y] = map[y][x] = v;
}
//初始化数组为最大值
for(i = 0; i < MAX; i++)
{
low[i] = INF;
}
low[1] = 0;
vis[1] = 1;
//初始化第一个顶点到其他点的权值,存进low数组
for(i = 2; i <= V; i++)
{
if(low[i] > map[1][i])
{
low[i] = map[1][i];
}
}
//遍历V-1次,每个点更新一次
for(i = 2; i <= V; i++)
{
int min = INF;
j = 2;
k = 0;
//每一轮挑出low数组里面最小值
while(j <= V)
{
if(vis[j] == 0 && low[j] < min)
{
min = low[j];
k = j;
}
j++;
}
vis[k] = 1; //每一轮挑出的最小值存放进low数组
//新最小值到达其余点的权值更新进low数组
for(j = 2; j <= V; j++)
{
if(vis[j] == 0 && low[j] > map[k][j] + low[k])//更新新的最小值的可达点
{
low[j] = map[k][j] + low[k];
}
}
}
answer = 0;
for(i = 2; i <= V; i++)
{
answer += low[i];
}
printf("%d", answer);
return 0;
}
/**************************************************************
Problem: 1024
User: lin005
Language: C++
Result: 正确
Time:10 ms
Memory:448 kb
****************************************************************/
1024
最新推荐文章于 2021-10-24 21:02:08 发布