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

        几乎所有涉及两点连成的边,并对集合类问题求解相关的问题,可考虑用并查集

    例子:

    题目1024:畅通工程 


    题目描述: 
        省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
    输入: 
        测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
    输出: 
        对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
    样例输入: 

    3 3
    1 2 1
    1 3 2
    2 3 4
    1 3
    2 3 2
    0 100
    样例输出:

    3
    ?
    来源: 2007年浙江大学计算机及软件工程研究生机试真题 

    思路:

    1.分清题目求解方向:求最小生成树还是求短路径。

    最小生成树:形成的集合中,是与所有点连接所需的最短距离;

    对短路径:一个点到另一个点的最短的距离。

    2.用某一点表示一类点的集合。

    框架:

    int find(int x)

    {

        if(root[x]!=-1)

        {

            int temp = findroot[x]);

            root[x] = temp;                                        //优化并查集:路径优化

            return temp;

        }

    else

        return x;

    }

    main:

    init(root);

    for(每条边)

    {

        int x = find(边得一端点序号);

        int y = find(边得另一端点序号);

        if(x!=y)                                            //变得两端点不是一个集合

        {

            root[x] = y;                                //将y归于x所在的集合

            process();                                    //处理数据,具体看例子

        }

    }

    我此题AC的源码:


    #include <iostream>
    #include <algorithm>
    using namespace std;

    struct edges
    {
    int x, y;
    int cost;
    }a[100];

    int tree[100];

    int find(int x)
    {
    if (tree[x]!=-1)
     {
      int temp = find(tree[x]);
      tree[x] = temp;
      return temp;
     }
    else
     {
      return x;
     }
    }

    int cmp(edges a,edges b)
    {
    return a.cost < b.cost;
    }

    int main()
    {
    int n, m;
    cin >> n;
    while (n!=0)
     {
      cin >> m;
      for (int i = 0; i < 100; i++)
      {
       tree[i] = -1;
      }

      for (int i = 0; i < n; i++)
      {
       cin >> a[i].x >> a[i].y >> a[i].cost;
      }

      sort(a, a + n,cmp);

      int ans = 0;
      int xiu = 0;
      for (int i = 0; i < n; i++)
      {
       int x = find(a[i].x);
       int y = find(a[i].y);
       if (x!=y)
       {
        tree[x] = y;
        ans += a[i].cost;
        xiu++;
       }
      }
      if (xiu == m-1)
      {
       cout << ans << endl;
      }
      else
      {
       cout << "?" << endl;
      }

      cin >> n;
     }

    return 0;
    }



    LOFTER:hgfalgorithm   http://hgfal.lofter.com/post/28eef2_10247ff
  • 相关阅读:
    用户体验
    jsp ini 配置文件
    Highcharts 图表
    简单游戏服务器
    js 数据操作
    jquery 导航
    as3.0 删除子元件
    java float 保留二位小数
    局域网ip
    SWFUpload
  • 原文地址:https://www.cnblogs.com/hgfgood/p/4248314.html
Copyright © 2011-2022 走看看