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

    2014.07.04 22:42

    简介:

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

    描述:

      本次使用Prim算法来解决这个问题。Prim算法的思想是两点:BFS与贪婪。

      我们从一个顶点出发,把这个顶点对应的边加入到优先队列中。既然是优先队列,当然是边的权值短的优先。

      每一轮我们从优先队列中取出一条边u->v,u已经被访问过(选出的这条边权值必然是目前最短的),如果v未被访问过,那么标记v,并把从v出发的边加入队列。

      这样从一点出发逐渐散开的搜索形式属于广度优先搜索,而短边优先的策略则属于贪婪。因此Prim算法就是BFS与贪婪算法的结合。

      说实话,直接看代码实现或许更简单。

    实现:

      1 // My implementation for Prim's Algorithm, for minimum spanning tree problem.
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <vector>
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int INFINITY = 1000000000;
      9 
     10 struct Edge {
     11     int x;
     12     int y;
     13     int cost;
     14     Edge(int _x = 0, int _y = 0, int _cost = 0): x(_x), y(_y), cost(_cost) {};
     15 };
     16 
     17 struct GreaterFunctor {
     18     bool operator () (const Edge &e1, const Edge &e2) {
     19         return e1.cost > e2.cost;
     20     }
     21 };
     22 
     23 int primsAlgorithm(const vector<vector<int> > &graph)
     24 {
     25     // Prim's Algorithm for weighted undirected graph.
     26     
     27     int n;
     28     n = (int)graph.size();
     29     if (n < 2) {
     30         return 0;
     31     }
     32 
     33     int i;
     34     // Minimal heap, the top is smallest.
     35     priority_queue<Edge, vector<Edge>, GreaterFunctor> pq;
     36     vector<bool> visited;
     37     int visited_count;
     38     int min_cost;
     39     
     40     visited.resize(n, false);
     41     
     42     // Start constructing the tree from 0th vertex.
     43     min_cost = 0;
     44     visited[0] = true;
     45     for (i = 1; i < n; ++i) {
     46         if (graph[0][i] == INFINITY) {
     47             continue;
     48         }
     49         pq.push(Edge(0, i, graph[0][i]));
     50     }
     51     visited_count = n - 1;
     52     
     53     Edge e;
     54     while (!pq.empty()) {
     55         e = pq.top();
     56         pq.pop();
     57         if (visited[e.y]) {
     58             continue;
     59         }
     60         min_cost += e.cost;
     61         visited[e.y] = true;
     62         --visited_count;
     63         if (visited_count == 0) {
     64             break;
     65         }
     66         
     67         for (i = 0; i < n; ++i) {
     68             if (i == e.y || graph[e.y][i] == INFINITY || visited[i]) {
     69                 continue;
     70             }
     71             pq.push(Edge(e.y, i, graph[e.y][i]));
     72         }
     73     }
     74     
     75     while (!pq.empty()) {
     76         pq.pop();
     77     }
     78     
     79     return min_cost;
     80 }
     81 
     82 int main()
     83 {
     84     vector<vector<int> > graph;
     85     int n;
     86     int nk;
     87     int i, j;
     88     int tmp, tmp_dist;
     89     int min_cost;
     90     
     91     while (cin >> n && n > 0) {
     92         graph.resize(n);
     93         for (i = 0; i < n; ++i) {
     94             graph[i].resize(n, INFINITY);
     95         }
     96         
     97         for (i = 0; i < n; ++i) {
     98             cin >> nk;
     99             for (j = 0; j < nk; ++j) {
    100                 cin >> tmp >> tmp_dist;
    101                 graph[i][tmp] = graph[tmp][i] = tmp_dist;
    102             }
    103         }
    104         
    105         min_cost = primsAlgorithm(graph);
    106         
    107         cout << "The weighted sum of minimum spanning tree is " << min_cost << "." << endl;
    108         
    109         for (i = 0; i < n; ++i) {
    110             graph[i].clear();
    111         }
    112         graph.clear();
    113     }
    114     
    115     return 0;
    116 }
  • 相关阅读:
    git 有用配置汇总
    C语言:不定长结构体的实现方式
    Linux 错误码
    执行insmod提示 invalid module format
    ARM GIC 系列文章学习(转)
    Android:高通平台Camera HFR Usecase分析
    索引图-查表-颜色缩减
    连通域查找【未完】
    epoll
    手动编译安装tmux
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3825215.html
Copyright © 2011-2022 走看看