http://acm.hdu.edu.cn/showproblem.php?pid=1875
畅通工程再续
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 33838 Accepted Submission(s): 11162
Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
Input
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
每组数据首先是一个整数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
Recommend
lcy
思路:
太难了,看了好多博客,大家竟然说这是入门题,呜啊,不想活了。
一开始使用了kruskal算法,结果超时了四五发,说起来还是心累,Prim不会堆优化,担心会超时,但还是决定试一试。
#include<stdio.h> #include<math.h> #define inf 2100000000 struct node { int x; int y; }is[105]; int main() { int T; int n; double a[105][105]; double dis[105]; int book[105]; scanf("%d",&T); while(T--){ for(int i=0;i<n;i++) book[i]=0; scanf("%d",&n); for(int i=0;i<n;i++){ for(int k=0;k<n;k++){ if(k==i){a[i][k]=0;} else a[i][k]=inf; } } for(int i=0;i<n;i++){ scanf("%d %d",&is[i].x,&is[i].y); } double __; for(int i=0;i<n;i++){ for(int k=i+1;k<n;k++){ __=sqrt((1.0*is[i].x-is[k].x)*(is[i].x-is[k].x)+(1.0*is[i].y-is[k].y)*(is[i].y-is[k].y)); //printf("%d %d %lf ",i,k,__); if(__>=10&&__<=1000)a[i][k]=a[k][i]=__; } } book[0]=1; for(int i=0;i<n;i++){ dis[i]=a[0][i]; } int num=n-1; double minn; int j; double sum=0; int flag=0; while(num>0){ minn=inf; flag=0; for(int i=0;i<n;i++){ if(book[i]==0&&dis[i]<minn){ minn=dis[i]; j=i; flag=1; } } if(flag==0){break;} book[j]=1;num--;sum+=dis[j]; for(int i=0;i<n;i++){ if(book[i]==0&&dis[i]>a[j][i]) dis[i]=a[j][i]; } } if(num>0){printf("oh! ");} else printf("%.1lf ",sum*100); } }
实在是没有想到,竟然一次就a了,看来真的蛮简单的嘛!