HDU 1875 畅通工程再续 最小生成树

本题其实就是求最小生成树,可以利用克鲁斯卡尔算法来解决。但是这里的边需要先处理出来,即把符合条件的边加入边集合中,这样就可以使用克鲁斯卡尔算法求解:排序+并查集检测连通性,最后得出结论。这里处理边的权重的时候没有直接处理double类型的数据,因为处理浮点型的数据有时候比较大小容易出错,而是保存的未开平方之前的int值,由题目数据可知这个值在100-1000000之间,所以保存起来排序也是比较方便的。


畅通工程再续

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12183    Accepted Submission(s): 3744


Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
 

Input
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
 

Output
每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
 

Sample Input
   
   
   
   
2 2 10 10 20 20 3 1 1 2 2 1000 1000
 

Sample Output
   
   
   
   
1414.2 oh!
 

Author
8600
 

Source
2008浙大研究生复试热身赛(2)——全真模拟
 

#include <cstdio>
#include <cstdlib>
#include <cmath>


const int MAX = 105;


const int L = 100;
const int R = 1000000;


int cnt;


double total;




typedef struct{
	int x,y;
	int cost;
}Point;


Point pot[MAX*MAX];//起初数组开小了,一直WA了三次,后来才想起边集数量最大可达到n*(n-1)/2


int pre[MAX],px[MAX],py[MAX];


int cal_len(int n){
	int i,j,tx,ty,len,pos;


	pos = 0;


	for(i=0;i<n;++i){
		for(j=i+1;j<n;++j){
			tx = px[i]-px[j];
			tx *= tx;
			ty = py[i]-py[j];
			ty *= ty;
			len = tx + ty;
			if(len>=L && len<=R){
				pot[pos].x = i;
				pot[pos].y = j;
				pot[pos].cost = len;
				++pos;
			}
		}
	}
	return pos;
}


void init(int n){
	int i;


	cnt = n-1;
	total = 0.0;
	for(i=0;i<n;++i){
		pre[i] = i;
	}
}


int root(int x){
	if(x!=pre[x]){
		pre[x] = root(pre[x]);
	}
	return pre[x];
}


int merge(int x,int y){
	int ret = 0;
	int fx = root(x);
	int fy = root(y);


	if(fx!=fy){
		--cnt;
		pre[fx] = fy;
		ret = 1;
	}
	return ret;
}


int cmp(const void *a,const void *b){
	Point *pa = (Point *)a;
	Point *pb = (Point *)b;


	return pa->cost-pb->cost;
}


int main(){
	int i,t,n;


	//freopen("in.txt","r",stdin);
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		
		init(n);


		for(i=0;i<n;++i){
			scanf("%d %d",&px[i],&py[i]);
		}


		int ln = cal_len(n);


		if(ln<n-1){
			printf("oh!\n");
			continue;
		}


	//	printf("%d******\n",ln);


		qsort(pot,ln,sizeof(Point),cmp);


		for(i=0;i<ln;++i){
			if(merge(pot[i].x,pot[i].y)==1){
				total += sqrt(pot[i].cost*1.0);
			}
		}


		if(cnt!=0){
			printf("oh!\n");
			continue;
		}else{
			printf("%0.1lf\n",total*100);
			continue;
		}
	}
	return 0;
}


你可能感兴趣的:(ACM,并查集,克鲁斯卡尔,浙大机试)