HDU ACM 1162 Eddy's picture

http://acm.hdu.edu.cn/showproblem.php?pid=1162

输入一个整数n,表示点的个数.

接下来n行,每行有两个浮点数表示点的x坐标y坐标.

构造一棵最小生成树.

 

用Kruskal做.

先算出各条边的权值.

再合并

//View Code
  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cmath>
  4 using namespace std;
  5 const int MAX = 10000 + 10;
  6 const int INF = 0x3fffffff;
  7 int father[MAX];
  8 int rank1[MAX];
  9 int sign[MAX];
 10 void Make_Set(int x)//初始化
 11 {
 12     father[x] = x;
 13     rank1[x] = 0;
 14 }
 15 
 16 int Find_Set(int x)//找根节点
 17 {
 18     int i=0;
 19     while(father[x] != x)
 20     {
 21         sign[i++] = x;
 22         x = father[x];
 23     }
 24     for(i;i>=1;i--)
 25     {
 26         father[sign[i-1]] = x;
 27     }
 28     return x;
 29 }
 30 
 31 void Union(int x,int y)//合并
 32 {
 33     x = Find_Set(x);
 34     y = Find_Set(y);
 35     if(x == y)
 36     {
 37         return;
 38     }
 39     if(rank1[x] > rank1[y])
 40     {
 41         father[y] = x;
 42     }
 43     else if(rank1[x] < rank1[y])
 44     {
 45         father[x] = y;
 46     }
 47     else if(rank1[x] ==rank1[y]) 
 48     {
 49         father[x] = y;           
 50         rank1[y]++;             
 51     }
 52 }
 53 struct Node
 54 {
 55     int start;
 56     int end;
 57     double num;
 58 };
 59 bool cmp(Node a,Node b)
 60 {
 61     return a.num < b.num;
 62 }
 63 Node num[MAX];
 64 double Kruskal(int n,int m)
 65 {
 66     int i;
 67     for(i=0;i<n;i++)
 68     {
 69         Make_Set(i);
 70     }
 71     double sum = 0;
 72     int mark = 0;
 73     for(i=0;i<m;i++)
 74     {
 75         int s = Find_Set(num[i].start);
 76         int e = Find_Set(num[i].end);
 77         if(s != e)
 78         {
 79             Union(num[i].start,num[i].end);
 80             sum += num[i].num;
 81         }
 82     }
 83     return sum;
 84 }
 85 int main()
 86 {
 87     int n;
 88     while(cin>>n)
 89     {
 90         double mid_x[MAX],mid_y[MAX];
 91         int i,j;
 92         for(i=0;i<n;i++)
 93         {
 94             cin>>mid_x[i]>>mid_y[i];
 95         }
 96         int m = 0;
 97         for(i=0;i<n;i++)
 98         {
 99             for(j=i+1;j<n;j++)
100             {
101                 num[m].num = sqrt((mid_x[i]-mid_x[j])*(mid_x[i]-mid_x[j]) + (mid_y[i]-mid_y[j])*(mid_y[i]-mid_y[j]));
102                 num[m].start = i;
103                 num[m].end = j;
104                 m++;
105             }
106         }
107         sort(num,num+m,cmp);
108         printf("%.2lf\n",Kruskal(m,m));
109     }
110     return 0;
111 }

 

posted @ 2012-09-06 21:01  zx雄  阅读(183)  评论(0编辑  收藏  举报