HDU-1162 Eddy's picture

Eddy's picture

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10685    Accepted Submission(s): 5397


Problem Description
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
暑期好难熬啊,心里很烦躁,好想回家啊,vj上没训练赛就不想做题,一早上也就写出了这题。
思想有,实现步骤还是有点不会,于是学习了一遍prim算法,相对于kruskal算法,
prim算法在处理边数较多,顶点较少的情况下还是比较高效的,而kruskal算法则更适合处理边数较少,顶点较多的情况。
 
ps:由这题简单介绍下prim算法。
百度百科告诉我们,prim是不断选取已经选取过的点的最小边,
这样我们就需要找出那条边是最小边了。我开始以为要用我们刚加入的点的最小边比较已经存在的点的最小边,
但是我发现这很难实现,内存开销很大。
看了模板之后发现我们只需要找到n-1条边就够了,最小的边,我们并不关心起点,只关心终止点。
这样我们就可以用个low数组来存没标记的点到树的最短距离。
这样我们就很好的解决这道题
 
 
 
其实这道题感觉也能用kruskal算法写,但是为了以后的做题还是学习一下prim算法。
题目大意:求最小生成树。
思路:prime算法或kruskal算法,前者验证了,后者还没验证。
ps:由于是浮点运算。所以要注意精度问题,尽量用double吧。
通过这道题我才知道原来输出浮点数不需要&。比如printf("%d",&x)需要&,但是浮点数则不用,只需printf("%.2lf",x) ,应该是浮点数在内存中的存储是字符串存储的。(个人猜测,O(∩_∩)Ohhhh)
没用过c的输出吧,看来以后要好好学习一下printf函数了。
AC代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<math.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<iomanip>
 7 #include<string.h>
 8 #define INF 99999999
 9 using namespace std;
10 int n;
11 struct Node{
12     double x,y;
13 }a[105];
14 double dis[105][105];
15 int flag[105];
16 double low[105];
17 double length(double x,double y){
18     double len=sqrt(x*x+y*y);
19     return len;
20 }
21 int prim()
22 {
23     double sum=0;
24     memset(flag,0,sizeof(flag));
25     int pos=1;
26     flag[pos]=1;
27     for(int i=1;i<=n;i++){
28         if(i!=1)
29             low[i]=dis[pos][i]; //给low数组初始化
30     }
31     for(int i=1;i<n;i++){
32         double mini=INF;  
33         for(int j=1;j<=n;j++){
34             if(!flag[j]&&mini>low[j]){
35                 mini=low[j];   //选取最小边
36                 pos=j;
37             }
38         }
39         flag[pos]=1;   //标记它
40         sum+=mini;
41         for(int j=1;j<=n;j++){    
42             if(!flag[j]&&low[j]>dis[pos][j]){   //比较未标记的点到j的距离近还是到树的距离近
43                low[j]=dis[pos][j]; 
44             }
45         }
46     }
47     printf("%.2lf\n",sum);    //浮点输出不用&
48 }
49 int main(){
50     while(cin>>n){
51         for(int i=1;i<=n;i++){
52             cin>>a[i].x>>a[i].y;
53         }
54         for(int i=1;i<=n;i++){
55             for(int j=1;j<=n;j++){
56                 if(i==j) dis[i][j]=0;
57                 else{
58                    double len;
59                    len=length(a[i].x-a[j].x,a[i].y-a[j].y);
60                    dis[i][j]=len;
61                 }
62             }
63         }
64         prim();
65     }
66     return 0;
67 }
68              

 

 
posted @ 2017-08-03 11:16  ISGuXing  阅读(201)  评论(0编辑  收藏  举报