Swordfish

zoj1203:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1203

题意:给定平面上N个城市的位置,计算连接这N个城市所需线路长度总和的最小值
题解:每两个点之间建一条边,然后求这一棵最小生成树。

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cmath>
 6 using namespace std;
 7 int n,pa[102],cnt,num;//分别记录点的个数 ,并查集,边的个数,以及处理的边的个数 
 8 struct Node{
 9     double x;
10     double y;
11 }node[102];//记录每个点 
12 struct Edge{
13     int u;
14     int v;
15     double w;
16     bool operator<(const Edge &a)const{
17         return w<a.w;}
18 }edge[10000];//记录每一条边,以及定义排序规则 
19 void UFset(){
20     for(int i=1;i<=n;i++)
21       pa[i]=-1;
22 }//初始化 
23 int Find(int x){//查找 
24     int s;
25     for(s=x;pa[s]>=0;s=pa[s]);
26     while(s!=x){
27         int temp=pa[x];
28         pa[x]=s;
29         x=temp;
30     }//路径压缩,便于后面的查找 
31     return s;
32 }
33 void Union(int R1,int R2){//合并,把个数的集合作为子树加到另一棵树上 
34     int r1=Find(R1);
35     int r2=Find(R2);
36     int temp=pa[r1]+pa[r2];
37     if(pa[r1]>pa[r2]){
38         pa[r1]=r2;
39         pa[r2]=temp;
40     }
41     else{
42         pa[r2]=r1;
43         pa[r1]=temp;
44     }
45 }
46 double dist(Node a,Node b){//计算每两个点之间距离 
47     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
48 }
49 double kruska(){//克鲁斯卡尔算法 
50         UFset();//初始化 
51         num=0;
52     double sum=0.0;
53     for(int i=0;i<cnt;i++){
54         int u=edge[i].u;
55         int v=edge[i].v;
56         if(Find(u)!=Find(v)){
57             sum+=edge[i].w;
58             num++;
59             Union(u,v);
60         }
61         if(num>=n-1)break;
62     }
63      return sum;
64 }
65 int main(){
66       int t=0;
67    while(~scanf("%d",&n)&&n){
68            cnt=0;//初始化 
69      for(int i=1;i<=n;i++)
70         scanf("%lf%lf",&node[i].x,&node[i].y);//存边 
71      for(int i=1;i<=n;i++){
72         for(int j=i+1;j<=n;j++){
73                 edge[cnt].u=i;
74                 edge[cnt].v=j;
75                 edge[cnt++].w=dist(node[i],node[j]);
76             }
77         }//建边,每两个点之间建一条边 
78         sort(edge,edge+cnt);//排序 
79        if(t)printf("
");
80      printf("Case #%d:
",++t);
81      printf("The minimal distance is: %.2f
",kruska());
82     }
83 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3370480.html