POJ 1797 kruskal 算法

Posted 小小八

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

  

以上是关于POJ 1797 kruskal 算法的主要内容,如果未能解决你的问题,请参考以下文章

poj 2377 拉最长的线问题 kruskal算法

ZOJ 1542 POJ 1861 Network 网络 最小生成树,求最长边,Kruskal算法

poj 1797 最大最小容量dijkstra (经典)

POJ 1797 最短路

POJ-2349(kruskal算法+最小生成树中最大边的长度)

ACM/ICPC 之 Kruskal范例(POJ1128(ZOJ1083))