您的位置:首页 > 其它

UVa 10147 - Highways

2015-04-03 18:43 344 查看
题目:在一个平面上有很多点,其中一些点已经被直线段连接,现在要把所有点连成一个整体,

要求新加入的直线段长度和最小。

分析:最小生成树。这里使用kruskal算法,先把一直线段的集合合并(并查集),然后在计算即可。

说明:╮(╯▽╰)╭。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

int smap[755][755];

typedef struct p_node
{
	int x,y;
}point;
point p[755];

int dist(point a, point b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

typedef struct d_node
{
	int	point1;
	int	point2;
	int	weight;
}enode;
enode edge[565000];

//union_set
int sets[755];
int rank[755];

void set_inital(int a, int b)
{
	for (int i = a; i <= b; ++ i) {
		rank[i] = 0;
		sets[i] = i;
	}
}

int  set_find(int a)
{
	if (a != sets[a])
		sets[a] = set_find(sets[a]);
	return sets[a];
}

void set_union(int a, int b)
{
	if (rank[a] < rank[b])
		sets[a] = b;
	else {
		if (rank[a] == rank[b])
			rank[a] ++;
		sets[b] = a;
	}
}
//end_union_set

int cmp_e(enode a, enode b)
{
	return a.weight < b.weight;
}

void kruskal(int n)
{
	set_inital(1, n);
	
	int r = 0,uni = 0;
	for (int i = 1; i <= n; ++ i)
	for (int j = 1; j < i; ++ j) 
		if (!smap[i][j]) {
			edge[r].point1 = j;
			edge[r].point2 = i;
			edge[r].weight = dist(p[i], p[j]);
			r ++;
		}else {
			int A = set_find(i);
			int B = set_find(j);
			if (A != B) {
				set_union(A, B);
				uni ++;
			}
		}
	
	if (uni+1 == n) {
		printf("No new highways need\n");
		return;
	}
	
	sort(edge, edge+r, cmp_e);
	int add = 0;
	for (int i = 0; i < r; ++ i) {
		int A = set_find(edge[i].point1);
		int B = set_find(edge[i].point2);
		if (A != B) {
			set_union(A, B);
			printf("%d %d\n",edge[i].point1,edge[i].point2);
			if (uni++ == n-1) {
				printf("No new highways need\n");
				return;
			}
		}
	}
}

int main()
{
	int t,n,m,a,b;
	while (scanf("%d",&t) != EOF)
	while (t --) {
		scanf("%d",&n);
		for (int i = 1 ; i <= n; ++ i)
			scanf("%d%d",&p[i].x,&p[i].y);
		scanf("%d",&m);
		memset(smap, 0, sizeof(smap) );
		for (int i = 1 ; i <= m; ++ i) {
			scanf("%d%d",&a,&b);
			smap[a][b] = smap[b][a] = 1;
		}
		
		kruskal(n);
		if (t) printf("\n");
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: