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

来源:互联网 发布:mac看照片时怎么删除 编辑:程序博客网 时间:2024/05/17 20:01

本题其实就是求最小生成树,可以利用克鲁斯卡尔算法来解决。但是这里的边需要先处理出来,即把符合条件的边加入边集合中,这样就可以使用克鲁斯卡尔算法求解:排序+并查集检测连通性,最后得出结论。这里处理边的权重的时候没有直接处理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
2210 1020 2031 12 21000 1000
 

Sample Output
1414.2oh!
 

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)/2int 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;}


0 0
原创粉丝点击