HDU-1875 畅通工程再续

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1875

分析:kruskal算法。先确保每个岛都有至少一条有效边与其他岛相连,然后直接kruskal即可。(但我出现了很意外的错误,在ide上如果用C++11之前会出现很神奇的错误,之后就没有,在vjudge上用G++可行)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 struct edge
 7 {
 8     int u,v;
 9     double w;
10 }e[110000];
11 struct point
12 {
13     int x,y;
14 }p[110];
15 int t,n,f[110],cnt,tot;
16 double ans;
17 int find(int k)
18 {
19     if(f[k]==k)return k;
20     return f[k]=find(f[k]);
21 }
22 double cmp(edge a,edge b)
23 {
24     return a.w<b.w;
25 }
26 double distance(int i,int j)
27 {
28     return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
29 }
30 void add(int u,int v,double w)
31 {
32     e[++cnt].u=u;
33     e[cnt].v=v;
34     e[cnt].w=w;
35 }
36 int main(void)
37 {
38     scanf("%d",&t);
39     while(t--)
40     {
41         tot=cnt=0;
42         ans=0;
43         int b=0;
44         scanf("%d",&n);
45         for(int i=1;i<=n;i++)
46         {
47             scanf("%d %d",&p[i].x,&p[i].y);
48             f[i]=i;
49         }
50         for(int i=2;i<=n;i++)
51         {
52             int p=0;
53             for(int j=1;j<i;j++)
54             {
55                 double d=distance(i,j);
56                 if(d<=1000&&d>=10)
57                 {
58                     add(i,j,d);
59                     p=1;
60                 }
61             }
62             if(p==0)
63             {
64                 printf("oh!\n");
65                 b=1;
66                 break;
67             }
68         }
69         if(b==1)continue;
70         sort(e+1,e+1+cnt,cmp);
71         for(int i=1;i<=cnt;i++)
72         {
73             int fu=find(e[i].u),fv=find(e[i].v);
74             if(fu==fv)continue;
75             f[fu]=fv;
76             ans+=e[i].w;
77             if(++tot==n-1)break;
78         }
79         printf("%.1f\n",ans*100);
80     }
81     return 0;
82 }

猜你喜欢

转载自www.cnblogs.com/yanying7/p/12738248.html