/*
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=372
题意:给定了n个点(1~n),和r条边,有些是重合的,求将n个点连起来的最短的边长和
分析:最小生成树 prim
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
const int maxn = 100000;
const int m = 55;
bool flag[m];
int lowcost[m], map[m][m];
int main(){
#ifndef ONLINE_JUDGE
freopen( "in", "r", stdin);
#endif
int n, r;
while(cin >>n, n){
cin >>r;
memset(map, -1, sizeof(map));
int x, y, length;
for(int i=1; i<=r; i++){
scanf("%d %d %d", &x, &y, &length);
if( (map[x][y] != -1 && map[x][y]>length) || map[x][y]==-1){
map[x][y] = length;
map[y][x] = length;
}
}
//lowcost[i]=-1表示U中没有点与V-U中的i点之间有路由
for(int i=2; i<=n; i++)
lowcost[i] = map[1][i];
int sum = 0;
//表示1在U中
lowcost[1] = 0;
int tag = 1;
for(int i=1; i<n; i++){
int Max = maxn;
for(int j=2; j<=n; j++){
//lowcost[j]>0表示j在V-U 中且U中有点与j之间有路由
if(lowcost[j]>0 && lowcost[j]<Max){
tag = j;
Max = lowcost[j];
}
}
sum += Max;
//将tag加入到U中
lowcost[tag] = 0;
for(int j=2; j<=n; j++){
//tag加入到U中之后要对路由进行更新,一定要注意map[tag][j]的判断
if( (lowcost[j]>0 && map[tag][j]<lowcost[j] && map[tag][j]!=-1) || lowcost[j]==-1 )
lowcost[j] = map[tag][j];
}
}
printf("%dn", sum);
}
return 0;
}
12-01
09-15
09-15