bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路(最小生成树)

1626: [Usaco2007 Dec]Building Roads 修建道路

Time Limit: 5 Sec   Memory Limit: 64 MB
Submit: 1709   Solved: 716
[ Submit][ Status][ Discuss]

Description

Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场)。有些农场之间原本就有道路相连。 所有N(1 <= N <= 1,000)个农场(用1..N顺次编号)在地图上都表示为坐标为(X_i, Y_i)的点(0 <= X_i <= 1,000,000;0 <= Y_i <= 1,000,000),两个农场间道路的长度自然就是代表它们的点之间的距离。现在Farmer John也告诉了你农场间原有的M(1 <= M <= 1,000)条路分别连接了哪两个农场,他希望你计算一下,为了使得所有农场连通,他所需建造道路的最小总长是多少。

Input

* 第1行: 2个用空格隔开的整数:N 和 M

 * 第2..N+1行: 第i+1行为2个用空格隔开的整数:X_i、Y_i * 第N+2..N+M+2行: 每行用2个以空格隔开的整数i、j描述了一条已有的道路, 这条道路连接了农场i和农场j

Output

* 第1行: 输出使所有农场连通所需建设道路的最小总长,保留2位小数,不必做 任何额外的取整操作。为了避免精度误差,计算农场间距离及答案时 请使用64位实型变量

Sample Input

4 1
1 1
3 1
2 3
4 3
1 4

Sample Output

4.00


最小生成树模板题

kuangbin带你飞里也有一道一样的,将已修建的路长度置为0就行

#include<stdio.h>
#include<math.h>
#include<string.h>
#define LL long long
typedef struct
{
	LL x;
	LL y;
}Point;
Point s[1005];
double road[1005][1005], bet[1005];
LL flag[1005];
int main(void)
{
	double k, ans;
	LL n, m, i, j, x, y, temp;
	while(scanf("%lld%lld", &n, &m)!=EOF)
	{
		for(i=1;i<=n;i++)
			scanf("%lld%lld", &s[i].x, &s[i].y);
		for(i=1;i<=n;i++)
		{
			for(j=i+1;j<=n;j++)
				road[i][j] = road[j][i] = sqrt(1.0*(s[i].x-s[j].x)*(s[i].x-s[j].x)+(s[i].y-s[j].y)*(s[i].y-s[j].y));
		}
		for(i=1;i<=m;i++)
		{
			scanf("%lld%lld", &x, &y);
			road[x][y] = road[y][x] = 0;
		}
		ans = 0;
		for(i=1;i<=n;i++)
			bet[i] = road[1][i];
		memset(flag, 0, sizeof(flag));
		flag[1] = 1;
		for(i=2;i<=n;i++)
		{
			k = 1ll<<50;
			for(j=2;j<=n;j++)
			{
				if(flag[j]==0 && bet[j]<k)
				{
					k = bet[j];
					temp = j;
				}
			}
			flag[temp] = 1;
			ans += k;
			for(j=2;j<=n;j++)
			{
				if(flag[j]==0 && road[temp][j]<bet[j])
					bet[j] = road[temp][j];
			}
		}
		printf("%.2f\n", ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值