Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
Hint
Hint
Huge input, scanf isrecommended.
思路:
Prim
程序:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define ll __int64
#define L(u) ((u)<<1)
#define R(u) ((u)<<1|1)
#define lowbit(x) ((x)&-(x))
#define Cnt1(n) (__builtin_popcount(n))
#define max(x,y) ((x>y)?(x):(y))
#define min(x,y) ((x<y)?(x):(y))
#define PB push_back
#define sq(x) ((x)*(x))
#define rep(i,x,y) for(i=x;i<=y;i++)
#define rep0(i,x,y) for(i=x;i<y;i++)
#define mem(a, num) memset(a, num, sizeof(a))
#define cpy(to, from) memcpy(to, from, sizeof(from))
#define sd(x) scanf("%d",&x)
#define sd2(x,y) scanf("%d%d",&x,&y)
#define sd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define slld(x) scanf("%I64d",&x)
#define slld2(x,y) scanf("%I64d%I64d",&x,&y)
#define slld3(x,y,z) scanf("%I64d%I64d%I64d",&x,&y,&z)
#define slf(x) scanf("%lf",&x)
#define slf2(x,y) scanf("%lf%lf",&x,&y)
#define sc(c) scanf("%c",&c);
#define ss(st) scanf("%s",st);
#define pd(x) printf("%d\n",x);
#define plld(x) printf("%I64d",x);
#define pcas() printf("Case %d: ", ++cas)
#define pn() putchar(10);
#define SA(a,i,n) rep(i,1,n) sd(a[i])
#define SA0(a, i, n) rep0(i,0,n) sd(a[i])
#define PA(a,i,n) rep0(i,1,n) printf("%d ", a[i]); pd(a[(n)])
#define PA0(a, i, n) rep0(i,0,(n)-1) printf("%d ", a[i]); pd(a[(n) - 1])
const int N = 105;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
const double pi = acos(-1.0);
int lowcost[N];
int closet[N];
int a[N][N];
int main()
{
int n;
while (sd(n) != EOF && n)
{
int i, j, k;
rep(i, 1, n)
rep(j, 1, n)
a[i][j] = INF;
rep(i, 1, n*(n - 1) / 2)
{
int x, y, l;
sd3(x, y, l);
a[x][y] = l;
a[y][x] = l;
}
rep(i, 1, n)
{
lowcost[i] = a[1][i];
closet[i] = 1;
}
lowcost[1] = 0;//起点的lowcost初始化为0
int mincost = 0;
rep0(i, 1, n)//循环(n-1)次
{
int temp = INF;
rep(j, 1, n)
if (lowcost[j] != 0 && lowcost[j]<temp)
temp = lowcost[j], k = j;
// 找到目前情况下能连上的权值最小的边的另一端点
lowcost[k] = 0;
mincost += a[closet[k]][k];
rep(j, 1, n)
if (a[k][j]<lowcost[j])
lowcost[j] = a[k][j], closet[j] = k;
//更新
}
printf("%d\n", mincost);
}
return 0;
}