zoukankan      html  css  js  c++  java
  • 《数据结构与算法分析:C语言描述》复习——第九章“图论”——Kruskal算法

    2014.07.04 23:03

    简介:

      给定一个无向带权连通图(三个条件),选出n-1条边将这n个顶点连成一棵树,使得这棵树的权值之和最小。

    描述:

      本次使用Kruskal算法来解决这个问题。

      如果有n个顶点的话,我们需要n-1条边来拼成一棵树。

      Kruskal算法的基本思路,是每次拼上一条边,看看是否会造成一个环,如果会形成环则放弃这条边。

      怎么保证拼成的那棵树权值最小呢?把所有边按权值由小到大排序。从小到大一个个试就可以了。

      怎么确定加入一条边后是否会形成环呢?用并查集。对于一条无向图的边u-v,如果并查集中u和v对应的根节点相同,代表u、v已经连通了,这时再加入u-v就会形成一个环。

      Kruskal算法可以说是学完并查集之后的第一个应用了。

      由于需要对所有边进行排序,所以Kruskal算法的效率对于密集图(和恐惧症无关)肯定不那么好。

    实现:

      1 // My implementation for Prim's Algorithm, for minimum spanning tree problem.
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <vector>
      5 using namespace std;
      6 
      7 const int INFINITY = 1000000000;
      8 
      9 struct Edge {
     10     int x;
     11     int y;
     12     int cost;
     13     Edge(int _x = 0, int _y = 0, int _cost = 0): x(_x), y(_y), cost(_cost) {};
     14 };
     15 
     16 bool comparator(const Edge &e1, const Edge &e2) {
     17     return e1.cost < e2.cost;
     18 }
     19 
     20 int findRoot(vector<int> &dj, int x)
     21 {
     22     int r, k;
     23     
     24     r = x;
     25     while (r != dj[r]) {
     26         r = dj[r];
     27     }
     28     
     29     // Path compression speeds up the disjoint set.
     30     k = x;
     31     while (x != r) {
     32         x = dj[x];
     33         dj[k] = r;
     34         k = x;
     35     }
     36     
     37     return r;
     38 }
     39 
     40 int kruskalsAlgorithm(const vector<vector<int> > &graph)
     41 {
     42     // Kruskal's Algorithm for weighted undirected graph.
     43     int n;
     44     n = (int)graph.size();
     45     if (n < 2) {
     46         return 0;
     47     }
     48     
     49     // Disjoint set
     50     vector<int> dj;
     51     vector<Edge> edges;
     52     int rx, ry;
     53     int i, j;
     54     
     55     for (i = 0; i < n; ++i) {
     56         for (j = i + 1; j < n; ++j) {
     57             if (graph[i][j] == INFINITY) {
     58                 continue;
     59             }
     60             edges.push_back(Edge(i, j, graph[i][j]));
     61         }
     62     }
     63     sort(edges.begin(), edges.end(), comparator);
     64 
     65     dj.resize(n);
     66     for (i = 0; i < n; ++i) {
     67         dj[i] = i;
     68     }
     69     
     70     int edge_count = n - 1;
     71     int min_cost = 0;
     72     int ec = (int)edges.size();
     73     for (i = 0; i < ec; ++i) {
     74         rx = findRoot(dj, edges[i].x);
     75         ry = findRoot(dj, edges[i].y);
     76         if (rx == ry) {
     77             continue;
     78         }
     79         dj[rx] = ry;
     80         findRoot(dj, edges[i].x);
     81         
     82         min_cost += edges[i].cost;
     83         --edge_count;
     84         if (edge_count == 0) {
     85             break;
     86         }
     87     }
     88     edges.clear();
     89     
     90     return min_cost;
     91 }
     92 
     93 int main()
     94 {
     95     vector<vector<int> > graph;
     96     int n;
     97     int nk;
     98     int i, j;
     99     int tmp, tmp_dist;
    100     int min_cost;
    101     
    102     while (cin >> n && n > 0) {
    103         graph.resize(n);
    104         for (i = 0; i < n; ++i) {
    105             graph[i].resize(n, INFINITY);
    106         }
    107         
    108         for (i = 0; i < n; ++i) {
    109             cin >> nk;
    110             for (j = 0; j < nk; ++j) {
    111                 cin >> tmp >> tmp_dist;
    112                 graph[i][tmp] = graph[tmp][i] = tmp_dist;
    113             }
    114         }
    115         
    116         min_cost = kruskalsAlgorithm(graph);
    117         
    118         cout << "The weighted sum of minimum spanning tree is " << min_cost << "." << endl;
    119         
    120         for (i = 0; i < n; ++i) {
    121             graph[i].clear();
    122         }
    123         graph.clear();
    124     }
    125     
    126     return 0;
    127 }
  • 相关阅读:
    使用 media 实现响应式布局
    Django组件的中间件
    Django组件的cookie和 session,用户认证组件
    Django的文件上传和分页
    Ajax
    Django模型层的多表操作(2)
    Django模型层的多表操作(1)
    Django的查询表记录
    Django2.0版本的路由层和ORM但表操作
    Django的路由层,视图层和模版层
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3825238.html
Copyright © 2011-2022 走看看