• 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;
    }
    

      

  • 相关阅读:
    HappyLeetcode45:Divide Two Integers
    HappyLeetcode44:Plus One
    HappyLeetcode43:Symmetric Tree
    HappyLeetcode42:Intersection of Two Linked Lists
    特征向量中心性(从文献中摘抄)
    二叉树(普通无规律)
    链式队列
    链式栈
    链表
    指针
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5296458.html
Copyright © 2020-2023  润新知