zoukankan      html  css  js  c++  java
  • POJ 1797 kruskal 算法

    题目链接:http://poj.org/problem?id=1797

    开始题意理解错。不说题意了。

    并不想做这个题,主要是想测试kruskal 模板和花式并查集的正确性。

    已AC;

    /*
    最小生成树 kruskal算法
    过程:每次选取没有参与构造最小生成树并且加入之后不会构成回路的边中权值最小的一条
    作为最小生成树的一条新边。直至选择了V-1条边。
    */
    
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #define maxn 2100
    using namespace std;
    
    int fa[maxn], r[maxn];
    
    void init(int n) {
        for (int i=1; i<=n; ++i) {
            fa[i] = i;
            r[i] = 1;
        }
    }
    
    int find_fa(int v) { // 递归式路径压缩
        if (fa[v] != v) fa[v] = find_fa(fa[v]);
        return fa[v];
    }
    
    /*int find_fa(int v) { // 非递归式路径压缩
        int k, j, r;
        r = v;
        while(r != fa[r])
            r = fa[r]; //找到根节点 记录在r上。
        k = v;
        while(k != r) {
            j = fa[k];
            fa[k] = r;
            k = j;
        }
        return r;
    }*/
    
    /*void unin(int u, int v) { // 非按秩合并
        int fau = find_fa(u);
        int fav = find_fa(v);
        if (fau != fav)
            fa[fav] = fau;
    }*/
    
    void unin(int u, int v) { // 按秩合并
        int fau = find_fa(u);
        int fav = find_fa(v);
        if (fau == fav) return;
    
        if (r[u] < r[v]) fa[fau] = fav;
        else {
            if (r[u] == r[v])
                r[u]++;
            fa[fav] = fau;
        }
    }
    
    struct Edge {
        int u, v, w;
    }edge[1000010];
    
    bool cmp(Edge a, Edge b) {
        return a.w > b.w;
    }
    
    int ans;
    int kruskal(int n, int m) { // 传入顶点个数n 和 边的个数m
        init(n);
        sort(edge, edge+m, cmp);
        ans = 0;
        int ret = 0; // 生成树的总权值
        int cnt = 0; // 已加入最小生成树的边的数量
    
        for (int i=0; i<m; ++i) {
            if (find_fa(1) == find_fa(n)) return -1;
            int u = edge[i].u;
            int v = edge[i].v;
            if (find_fa(u) != find_fa(v)) {
                cnt++;
                ret += edge[i].w;
                unin(u, v);
                ans = edge[i].w;
            }
            if (cnt == n-1) return ret; // 已找到n-1条边,生成树构造完毕
        }
        return -1;
    }
    
    int main() {
        int casee = 1;
        int t;
        cin >> t;
        while(t--) {
            int n, m;
            cin >> n >> m;
            for (int i=0; i<m; ++i) {
                cin >> edge[i].u >> edge[i].v >> edge[i].w;
            }
            kruskal(n, m);
            cout << "Scenario #" << casee++ << ":" << endl << ans << endl << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    决策表快速排序
    书摘
    读书笔记
    echarts x y轴设置
    echarts图类型设置
    echarts入门
    jqgride实现多选
    jqgride实现每一行的单选
    Mac react环境搭建
    两列布局,三列布局
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5296458.html
Copyright © 2011-2022 走看看