• 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;
    }
    
  • 相关阅读:
    十六、JSONObject与JSONArray使用-不刷新页面做回写显示
    十二、js去掉空格_比较字符长度_中英文判断_页面初始化_简体字与繁字体判断
    十、页面加载时对复选框、下拉列表、单选框默认进行选中及提交请求时判断单选按钮是否选中
    一、什么是Velocity及简单示例
    十八、oracle查看、扩展表空间及linux服务器硬盘容量大小查看
    接口限流算法
    浅析负载均衡的6种算法,Ngnix的5种算法
    今天是JAVA诞生日
    浅谈Spring中JDK动态代理与CGLIB动态代理
    Docker基本命令汇总
  • 原文地址:https://www.cnblogs.com/littlepage/p/13082455.html
Copyright © 2020-2023  润新知