HDU 1875 畅通工程再续
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!
思路:
最小生成树问题,此题用Prime和kruskal算法,都行。处理的时候,如果两岛间的距离如果<10 || >1000,将其设为Max.即可、
AC代码如下:
1 #include <stdio.h>
2 #include <string.h>
3 #include<math.h>
4 #define max 9999999
5 double map[110][110],lowcost[110];
6 int visit[110];
7 int N;
8
9 struct Point
10 {
11 double x,y;
12 }p[210];
13
14 int main()
15 {
16 int i,j,t,k;
17 double temp,x1,y1,min;
18 scanf("%d",&t);
19 while(t--)
20 {
21 memset(map,0,sizeof(map));
22 memset(visit,0,sizeof(visit));
23 memset(lowcost,0,sizeof(lowcost));
24 int flag=1;
25 scanf("%d",&N);
26 for(i=1;i<=N;i++)
27 scanf("%lf %lf",&p[i].x,&p[i].y);
28 for(i=1;i<=N;i++)
29 for(j=1;j<=N;j++)
30 {
31 x1=(p[i].x-p[j].x)*(p[i].x-p[j].x);
32 y1=(p[i].y-p[j].y)*(p[i].y-p[j].y);
33 temp=sqrt(x1+y1);
34 if(temp<10||temp>1000)
35 map[i][j]=map[j][i]=max;
36 else
37 map[i][j]=map[j][i]=temp;
38 }
39
40 double sum=0.0;
41 visit[1]=1;
42 for(i=1;i<=N;i++)
43 lowcost[i]=map[1][i];
44 for(i=2;i<=N;i++)
45 {
46 min=max;
47 for(j=1;j<=N;j++)
48 if(lowcost[j]<min&&!visit[j])
49 {
50 k=j;
51 min=lowcost[j];
52 }
53 if(min==max||min<10)
54 {
55 flag=0;
56 break;
57 }
58 sum+=min;
59 visit[k]=1;
60 for(j=1;j<=N;j++)
61 if(lowcost[j]>map[k][j]&&!visit[j])
62 lowcost[j]=map[k][j];
63 }
64 if(flag==1)
65 printf("%.1lf\n",sum*100.0);
66 else
67 printf("oh!\n");
68 }
69 return 0;
70 }