HDU 1233 - 还是畅通工程

3 篇文章 0 订阅
1 篇文章 0 订阅

Problem Description

某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

 

 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1N编号。
N0时,输入结束,该用例不被处理。

 

 

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值