POJ2560 (最小生成树模板题)

In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to form a picture of the Liberty Bell. Alas, one of the freckles turns out to be a scar, so his Ripley's engagement falls through. 
Consider Dick's back to be a plane with freckles at various (x,y) locations. Your job is to tell Richie how to connect the dots so as to minimize the amount of ink used. Richie connects the dots by drawing straight lines between pairs, possibly lifting the pen between lines. When Richie is done there must be a sequence of connected lines from any freckle to any other freckle.

Input

The first line contains 0 < n <= 100, the number of freckles on Dick's back. For each freckle, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the freckle.

Output

Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the freckles.

Sample Input

3
1.0 1.0
2.0 2.0
2.0 4.0

Sample Output

3.41

 题意:给你n个点,求能把这n个点连起来所用的最少墨水

最小生成树的模板题:一旦两个点已经被连线,那么再出现的时候就不能再连,否则会浪费墨水,这时就用到了并查集的思想,一旦两个点的父亲节点相同,则他们之间便有了线,不用再连。而n个点最少需要n-1条边来连接。注意POJ的题目能用c++就不要用G++,因为莫名其妙就会出错

请看代码:

 1 #include <iostream>
 2 #include <math.h>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <string>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 struct node
11 {
12   double x,y;
13 };
14 
15 struct code
16 {
17   int x,y;
18   double v;
19 };
20 
21 bool cmp(code a,code b)
22 {
23   return a.v<b.v;
24 }
25 
26 int const N=110;
27 node a[N];
28 int father[N];
29 code b[N*N];
30 
31 int Find(int a)
32 {
33   int b=a;
34   while(b!=father[b]) b=father[b];
35   while(a!=father[a])
36   {
37     int x=father[a];
38     father[a]=b;
39     a=x;
40   }
41   return b;
42 }
43 
44 void Union(int x,int y)
45 {
46   int fx=Find(x);
47   int fy=Find(y);
48   if(fx!=fy) father[fx]=fy;
49 }
50 
51 int main()
52 {
53   int m;
54   while(~scanf("%d",&m))
55   {
56     for(int i=1;i<=m;i++) scanf("%lf %lf",&a[i].x,&a[i].y);
57     for(int i=1;i<=m;i++) father[i]=i;
58     int p=1;
59     for(int i=1;i<m;i++)
60     {
61        for(int j=i+1;j<=m;j++)
62        {
63           b[p].x=i;
64           b[p].y=j;
65           b[p].v=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
66           p++;
67        }
68      }
69      sort(b+1,b+p,cmp);
70      double ans=0;
71      int k=0;
72      for(int i=1;i<p;i++)
73      {
74        if(Find(b[i].x)==Find(b[i].y)||k==m-1) continue;
75        Union(b[i].x,b[i].y);
76        ans+=b[i].v;
77        k++;
78      }
79      printf("%.2lf
",ans);
80    }
81   return 0;
82 }
原文地址:https://www.cnblogs.com/Amidgece/p/5721961.html