HDOJ1875(畅通工程再续)

题目链接

这题与HDOJ1879有点不太一样,不能把不符合条件的边看成是已经修好的,使用克鲁斯卡尔时,碰到不符合的边直接跳过即可。

View Code
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <math.h>
 4 #define D(x1,y1,x2,y2)  (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)))
 5 #define N 101
 6 #define M 5000
 7 int x[N],y[N];
 8 struct node
 9 {
10     int a,b;
11     double d;
12 }edge[M];
13 int n,m,p[N];
14 void make_set()
15 {
16     int i;
17     for(i=0;i<n;i++)   p[i]=i;
18 }
19 int find_set(int i)
20 {
21     return i==p[i]?p[i]:(p[i]=find_set(p[i]));
22 }
23 void union_set(int i,int j)
24 {
25     i=find_set(i),j=find_set(j);
26     p[j]=i;
27 }
28 int cmp(const void *a,const void *b)
29 {
30     double x,y;
31     x=((struct node*)a)->d;
32     y=((struct node*)b)->d;
33     if(x>y) return 1;
34     return -1;
35 }
36 int main()
37 {
38     int t,i,j,cnt;
39     double ans;
40     scanf("%d",&t);
41     while(t--)
42     {
43         scanf("%d",&n);
44         make_set();
45         for(i=0;i<n;i++)    scanf("%d%d",&x[i],&y[i]);
46         m=0;
47         for(i=0;i<n;i++)
48         {
49             for(j=i+1;j<n;j++)
50             {
51                 edge[m].a=i,edge[m].b=j;
52                 edge[m++].d=D(x[i],y[i],x[j],y[j]);
53             }
54         }
55         qsort(edge,m,sizeof(edge[0]),cmp);
56         ans=cnt=0;
57         for(i=0;cnt<n-1&&i<m;i++)
58         {
59             if(find_set(edge[i].a)==find_set(edge[i].b))  continue;
60             if(edge[i].d<10.0||edge[i].d>1000.0)    continue;
61             ans+=edge[i].d;
62             union_set(edge[i].a,edge[i].b);
63             cnt++;
64         }
65         if(cnt==n-1)    printf("%.1lf\n",ans*100);
66         else    printf("oh!\n");
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/algorithms/p/2460631.html