• 最小生成树与次小生成树


    题意:给出两个不同方案,每个方案使得所有的城堡被连通(形成连通图),同时使边权之和尽量小,问第一个方案与第二个方案的大小关系。

    解题思路:
    因为m个桥能使n个城堡联通,而两个大爷的方案中至少存在一个桥不相同,那么我们判断这是一个求次小生成树的方法。
    求次小生成树模板:
    https://blog.csdn.net/alice_991/article/details/48225949
    枚举+删边+再求MST复杂度有点高,看题解上面容易tle,所以采用上面链接里面的那种算法,为了复习并查集就用了Kruskal,复杂度为(N*2)

    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    
    const int maxn = 2e5+5;
    struct node {
        int u, v;
        ll w;
        bool operator < (node& rhs) {
            return w < rhs.w;
        }
    }g[maxn];
    int n, m, pre[2005];
    
    int findset(int x) {
        return x == pre[x] ? pre[x] : pre[x] = findset(pre[x]);
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            pre[i] = i;
        }
        int x, y;
        ll w;
        for (int i = 0; i < m; i++) {
            scanf("%d%d%lld", &x, &y, &w);
            g[i].u = x; 
            g[i].v = y; 
            g[i].w = w;
        }
        int v1 = 0, v2 = 0, i, j;
        sort(g, g + m);
        for (i = 0; i < m; ) {
            for (j = i; j < m && g[j].w == g[i].w; j++) {
                int u = findset(g[j].u);
                int v = findset(g[j].v);
                if (u != v) v1++;
            }
            for (j = i; j < m && g[j].w == g[i].w; j++) {
                int u = findset(g[j].u);
                int v = findset(g[j].v);
                if (u != v) {
                    v2++; pre[u] = v;
                }
            }
            if (v2 == n - 1) break;
        }
        if (v2 < n - 1 || v1 > v2) printf("zin
    ");
        else printf("ogisosetsuna
    ");
        return 0;
    }
  • 相关阅读:
    给msde加装企业管理器
    InterBase 数据库与驱动 版本不同
    delphi 演示数据路径
    TNetHTTPClient 使用
    MYSQL之库操作
    MYSQL之数据操作
    MYSQL之表操作
    MYSQL之视图、触发器、存储过程、函数、事物、数据库锁和数据库备份
    数据库三范式详解
    MYSQL之索引原理与慢查询优化
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9489826.html
Copyright © 2020-2023  润新知