zoukankan      html  css  js  c++  java
  • Prim算法和Kruskal算法

    以数据结构算法 7-11 进行解释

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

    输入格式:

    输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。

    输出格式:

    输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。

    输入样例:

    6 15
    1 2 5
    1 3 3
    1 4 7
    1 5 4
    1 6 2
    2 3 4
    2 4 6
    2 5 2
    2 6 6
    3 4 6
    3 5 1
    3 6 1
    4 5 10
    4 6 8
    5 6 3
    

    输出样例:

    12
    

    这题采用Prim算法或者Kruskal算法,但是Kruskal算法需要进行写一个并查集进行判断连通性,所以选择Prim算法进行写。

    Prim算法

    #include <iostream>
    #include <queue>
    #include <vector>
    #define INF 999999
    using namespace std;
    int N, M, a, b, c;
    int e[1010][1010] = {0}, dist[1010], vis[1010] = {0};
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    int main() {
        scanf("%d%d", &N, &M);
        while(M--) {
            scanf("%d%d%d", &a, &b, &c);
            e[a][b] = e[b][a] = c;
        }
        fill(dist, dist + 1010, INF);
        dist[1] = 0;
        q.push({0, 1});
        while(q.size()) {
            int u = q.top().second;
            q.pop();
            if(vis[u]) continue;
            vis[u] = 1;
            for(int v = 1; v <= N; v++) {
                if(!vis[v] && e[u][v] && dist[v] > e[u][v])  {
                    dist[v] = e[u][v]; 
                    q.push({dist[v], v});
                }
            }
        }
        int sum = 0, conn = 1;
        for(int i = 1; i <= N; i++) {
            sum += dist[i];
            if(!vis[i]) conn = 0;
        }
        if(!conn) printf("-1
    ");
        else printf("%d
    ", sum);
        
        return 0;
    }
    

    Kruskal算法(这边未加入并查集判断连通性)

    #include <iostream>
    #include <queue>
    #include <vector>
    #define INF 999999
    using namespace std;
    int N, M, a, b, c;
    int vis[1010] = {0};
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    int main() {
        scanf("%d%d", &N, &M);
        while(M--) {
            scanf("%d%d%d", &a, &b, &c);
            q.push({c, a * 10000 + b});
        }
        int sum = 0, conn = 1;
        while(q.size()) {
            int m = q.top().second / 10000;
            int n = q.top().second % 10000;
            if(!vis[m] || !vis[n]) {
                sum += q.top().first;
                vis[m] = vis[n] = 1;
            }
            q.pop();
        }
        printf("%d
    ", sum);
        return 0;
    }
    
  • 相关阅读:
    软件工程--团队作业3
    软件工程--团队作业2
    软件工程第二次作业---结对编程
    软件工程第一次作业补充
    软件工程第一次作业
    用Use Case获取需求的方法是否有什么缺陷,还有什么地方需要改进?
    买卖股票的最佳时机
    爬楼梯
    删除排序数组中的重复数字
    1500802035王叔文
  • 原文地址:https://www.cnblogs.com/littlepage/p/13082455.html
Copyright © 2011-2022 走看看