zoukankan      html  css  js  c++  java
  • ZOJ 1203 Swordfish Kruskal算法求最小生成树

    就是如题的做法,在一个连通图中找一条最小生成树,Kruskal的思想就是先根据所有边的权值按小到大排序,然后依次选择边进最小生成树里,但是要排除该边加进去后出现了环,生成树里是不能有环的,这样的边就不能加入,在挑选了n-1(n为图中点的个数)条边后就结束,可以证明这样构造出来的图就是最小生生成树。

    再判断是否会出现环时用到并查集。

    int temp = parent[r1] +parent[r2];//两根结点所带结点的总数,因为写错了这句,我检查了N久,砸墙,我很激动地写成了 int temp = Find(r1)+Find(r2);

    然后各种程序各种混乱了。还有一点因为没有看见说每两个case中间要输出一个空行,然后PE了,然后改成在每个case后输两个换行符,结果还是PE,郁闷,最后只好在case输出结果之前写了一句if(不是第一个case) 输出换行。。。。。

    贴代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cmath>
      5 #define MAXN  120
      6 #define MAXM 6000
      7 using namespace std;
      8 int n,m;  //n为城市的个数,m为边的数目m = C(n,2)
      9 struct point   //平面上的一个点
     10 {
     11     double x,y;
     12 } city[MAXN];  //存各个城市的位置
     13 struct ArcNode
     14 {
     15     int u,v;  //一条边的起点和终点
     16     double w;  //边的长度,也就是两城市间的距离
     17     bool operator <(const ArcNode & other) const
     18     {
     19         if(w < other.w) return true;
     20         else return false;
     21     };
     22 } edge[MAXM];  //存边
     23 int parent[MAXN];  //用于并查集
     24 double dis(point a,point b)  //求两城市间距离函数
     25 {
     26     double d =sqrt((a.x - b.x) *(a.x - b.x)  + (a.y - b.y) *(a.y - b.y) );
     27     return d;
     28 }
     29 int Find(int x)
     30 {
     31     int s;
     32     for(s = x; parent[s] >= 0; s = parent[s]);
     33     while(s != x)
     34     {
     35         int temp = parent[x];
     36         parent[x] = s;
     37         x = temp;
     38     }
     39     return s;
     40 }
     41 void Union(int x,int y)
     42 {
     43     int r1 = Find(x);
     44     int r2 = Find(y);
     45     int temp = parent[r1] +parent[r2];//两根结点所带结点的总数
     46     if(parent[r1] > parent[r2])
     47     {
     48         parent[r1] = r2;
     49         parent[r2] = temp;
     50     }
     51     else
     52     {
     53         parent[r2] = r1;
     54         parent[r1] = temp;
     55     }
     56 }
     57 double  Kruskal()
     58 {
     59     int i;
     60     for(i=0; i<n; i++)
     61         parent[i] = -1;
     62     int num =0;
     63     double sum = 0;
     64     sort(edge,edge+m);
     65     for(i=0; i<m; i++)
     66     {
     67         int u = edge[i].u;
     68         int v = edge[i].v;
     69         if(Find(u) != Find(v))
     70         {
     71             Union(u,v);
     72             sum += edge[i].w;
     73             num++;
     74         }
     75         if(num >= n-1) break;
     76     }
     77     return sum;
     78 }
     79 int main()
     80 {
     81 //    freopen("in.cpp","r",stdin);
     82     int ser = 0;
     83     int i,j;
     84     while(~scanf("%d",&n) && n!=0)
     85     {
     86         for(i=0; i<n; i++)
     87             scanf("%lf%lf",&city[i].x,&city[i].y);
     88         m = 0;
     89         for(i=0; i<n; i++)
     90         {
     91             for(j=i+1; j<n; j++)
     92             {
     93                 edge[m].u = i;
     94                 edge[m].v = j;
     95                 edge[m].w = dis(city[i],city[j]);
     96                 m++;
     97             }
     98         }
     99         ser++;
    100         if( ser != 1) printf("\n");
    101         printf("Case #%d:\n",ser);
    102         printf("The minimal distance is: %.2lf\n",Kruskal());
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    poj 1035 (Spell checker )
    poj 3080 (暴力 strstr)
    kmp 模版
    匈牙利算法模版
    poj 1274 The Perfect Stall (最大匹配)
    hdu 1083 Courses(二分图 )
    pku 3363(内部测试赛)
    Linux 下联网脚本文件
    Qt 多国语言
    引用和引用参数
  • 原文地址:https://www.cnblogs.com/allh123/p/2991193.html
Copyright © 2011-2022 走看看