POJ 1751 Highways(最小生成树,kruskal)

62 篇文章 0 订阅

题目意思:
给出n个镇,已经修好了m条高速公路,要求在修 剩下的某些高速公路,使得n个镇连通,而费用最少。
本题要点:
1、 先把m条修好的高速公路的距离改为0, 然后用 kruskal 算法模拟;
2、 vis[i][j]表示镇 i和镇j是否已经有高速公路;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int MaxN = 760;
int n, m, tot, ans_cnt;
int fa[MaxN];
bool vis[MaxN][MaxN];	

struct Point
{
	int x, y;
}points[MaxN], ans[MaxN];

struct rec
{
	int x, y;
	double z;
	bool operator<(const rec& rhs) const
	{
		return z < rhs.z;
	}
}edge[MaxN * MaxN];

int get(int x)
{
	if(x == fa[x])
	{
		return x;
	}
	return fa[x] = get(fa[x]);
}

int main()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &points[i].x, &points[i].y);
	}
	tot = 0;
	int x, y;
	scanf("%d", &m);
	for(int i = 0; i < m; ++i)	// m条边已经建好
	{
		scanf("%d%d", &x, &y);
		vis[x][y] = vis[y][x] = true;
	}
	double x1, x2, y1, y2;
	for(int i = 1; i <= n; ++i)
	{
		for(int j = i + 1; j <= n; ++j)
		{
			edge[++tot].x = i, edge[tot].y = j;
			if(vis[i][j])
			{
				edge[tot].z = 0;
				continue;
			}
			x1 = points[i].x, x2 = points[j].x, y1 = points[i].y, y2 = points[j].y;
			edge[tot].z = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));  
		}
	}
	sort(edge + 1, edge + tot + 1);
	for(int i = 1; i <= n; ++i)
	{
		fa[i] = i;
	}
	int u, v;
	for(int i = 1; i <= tot; ++i)
	{
		u = edge[i].x, v = edge[i].y;
		x = get(u);
		y = get(v);
		if(x == y)
		{
			continue;
		}
		fa[x] = y;
		if(!vis[u][v])	
		{
			ans[ans_cnt].x = u, ans[ans_cnt++].y = v;
		}
	}
	for(int i = 0; i < ans_cnt; ++i)
	{
		printf("%d %d\n", ans[i].x, ans[i].y);
	}
	return 0;
}

/*
9
1 5
0 0 
3 2
4 5
5 1
0 4
5 2
1 2
5 3
3
1 3
9 7
1 2
*/

/*
1 6
3 7
4 9
5 7
8 3
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值