1. 程式人生 > 實用技巧 >HDU1162 Eddy's picture

HDU1162 Eddy's picture

Eddy begins to like painting pictures recently ,he is sure of himself to become a painter.Every day Eddy draws pictures in his small room, and he usually puts out his newest pictures to let his friends appreciate. but the result it can be imagined, the friends are not interested in his picture.Eddy feels very puzzled,in order to change all friends 's view to his technical of painting pictures ,so Eddy creates a problem for the his friends of you.
Problem descriptions as follows: Given you some coordinates pionts on a drawing paper, every point links with the ink with the straight line, causes all points finally to link in the same place. How many distants does your duty discover the shortest length which the ink draws?

Input

The first line contains 0 < n <= 100, the number of point. For each point, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the point.

Input contains multiple test cases. Process to the end of file.


Output

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

3
1.0 1.0
2.0 2.0
2.0 4.0

Sample Output

3.41

題意:埃迪最近開始喜歡畫畫,他很確定自己會成為畫家。每天,埃迪都會在自己的小房間裡畫畫,他通常會放出最新的畫來讓他
的朋友欣賞。但是結果是可以想像的,朋友們對他的畫不感興趣。埃迪感到非常困惑,為了將所有朋友的看法改變為他的繪畫技術,
所以埃迪給你的朋友們帶來了麻煩。 問題描述如下:給定圖紙上的一些座標點,每個點都與墨水用直線連結,導致所有點最終連結
在同一位置。您的職責發現墨跡繪製的最短距離是多少個距離?
輸入:第一行包含0 <n <= 100點的數量。對於每個點,都會跟隨一條線;接下來的每一行包含兩個實數,表示該點的(x,y)坐
標。輸入包含多個測試用例。處理到檔案末尾。
輸出:您的程式將一個實數列印到兩位小數:可以連線所有點的墨水線的最小總長度。

標籤:最小生成樹
Kruskal演算法:
我們從最小邊權的邊開始,按邊權從小到大依次加入,如果某次加邊產生了環,就扔掉這條邊,直到加入了n-1條邊,即形成了一棵樹。
Prim演算法
從任意一個結點開始,將結點分成兩類:已加入的,未加入的。每次從未加入的結點中,找一個與已加入的結點之間邊權最小值最小的結點。
然後將這個結點加入,並連上那條邊權最小的邊。重複n-1次。
本題我用的是kruskal演算法
程式碼如下:


 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6 int book[110];  //作為標記陣列 
 7 struct node{
 8     int start,end;    //起點,終點,以及距離 
 9     double vlu;
10 }stu[10010];
11 int cmp(node a,node b){
12     return a.vlu<b.vlu;
13 }
14 int find(int m){
15     int p=m;
16     while(p!=book[p])
17     p=book[p];
18     return p;
19 }
20 int join(int pa,int pb){
21     int na=find(pa);
22     int nb=find(pb);
23     if(na!=nb){  //判斷是不是環 
24         book[na]=nb;
25         return 1;
26     }
27     return 0;
28 }
29 int main(){
30     int n;
31     double x[110],y[110];
32     while(scanf("%d",&n)!=EOF){
33         for(int i=0;i<110;i++){
34             book[i]=i;
35         }
36         for(int i=0;i<n;i++){
37             scanf("%lf%lf",&x[i],&y[i]);
38         }
39         int k=0;
40         for(int i=0;i<n;i++){
41             for(int j=i+1;j<n;j++){
42                 stu[k].start=i;
43                 stu[k].end=j;
44                 stu[k].vlu=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
45                 k++;
46             }    
47         }
48         sort(stu,stu+k,cmp); //排序  邊值從小到大依次加入 
49         double sum=0.00;
50         for(int i=0;i<k;i++){
51             if(join(stu[i].start,stu[i].end))
52             sum+=stu[i].vlu;
53         }
54         printf("%.2lf\n",sum);
55     }
56     return 0;
57 }