zoukankan      html  css  js  c++  java
  • 最小生成树问题(并查集解决)

            传统的Prim算法或者是Kruskal算法求最小生成树时,要先把图创建出来,就比较麻烦。

            如果用并查集来解决,依次选取权值最小的边,判断它们是否在一个并查集内,如果在则舍去,如果不在则加入,简单了很多。

    题目描述

        某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

    输入描述:

        测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
        当N为0时,输入结束,该用例不被处理。

    输出描述:

        对每个测试用例,在1行里输出最小的公路总长度。
    示例1

    输入

    3
    1 2 1
    1 3 2
    2 3 4
    4
    1 2 1
    1 3 4
    1 4 1
    2 3 3
    2 4 2
    3 4 5
    0
    

    输出

    3
    5

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 
     5 int Find( int x);
     6 int Union(int x, int y);
     7 int cmp( const void *a, const void *b);
     8 
     9 typedef struct Edge
    10 {
    11     int a,b;
    12     int cost;
    13 } Edge;
    14 Edge edge[6002];
    15 int bcj[102];
    16 
    17 int main()
    18 {
    19     int n,m;
    20     int i;
    21     int ans,flag;
    22     while( scanf("%d",&n)!=EOF)
    23     {
    24         if( n==0)  break;
    25         m = n*(n-1)/2;
    26         memset( bcj,-1,102*sizeof(int));  //并查集初始化
    27         ans =0;
    28         for( i=0; i<m; i++)
    29         {
    30             scanf("%d %d %d",&edge[i].a,&edge[i].b,&edge[i].cost);
    31 
    32         }
    33         qsort( edge,m,sizeof(edge[0]),cmp);  //依据权值进行快速升序排序
    34 
    35         for( i=0; i<m; i++)
    36         {
    37             flag = Union( edge[i].a,edge[i].b);  //判断一条边的两个端点是否在一个并查集内
    38             if( flag==1 ) ans += edge[i].cost;  //如果不在一个并查集内则加该边权值
    39         }
    40         printf("%d
    ",ans);
    41     }
    42     return 0;
    43 }
    44 
    45 int Find( int x)
    46 {
    47     if( bcj[x]<0 ) return x;
    48     return bcj[x] = Find( bcj[x]);
    49 }
    50 
    51 int Union(int x, int y)
    52 {
    53     x = Find( x );
    54     y = Find( y );
    55 
    56     if( x==y ) return 0;
    57 
    58     bcj[x] += bcj[y];
    59     bcj[y] = x;
    60     return 1;
    61 
    62 }
    63 
    64 int cmp( const void *a, const void *b)
    65 {
    66     Edge *c = (Edge *)a;
    67     Edge *d = (Edge *)b;
    68     return c->cost - d->cost;
    69 }
    在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!
  • 相关阅读:
    redis入门
    elementui入门
    1387:搭配购买(buy)
    P1536 村村通
    1388:家谱(gen)
    1389:亲戚
    1385:团伙(group)
    P1305 新二叉树
    P5076 【深基16.例7】普通二叉树(简化版)
    二叉搜索树(BST)模版
  • 原文地址:https://www.cnblogs.com/yuxiaoba/p/8447324.html
Copyright © 2011-2022 走看看