• 次小生成树


    次小生成树

    非严格

    #include <cstring>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    const int N = 1111;
    const int M = 2 * N * N;
    int n, m;
    struct edge {
        int u, v, w;
        bool choose;
    }e[M];
    bool cmp(edge a, edge b) {return a.w < b.w;}
    int h[M], ne[M], to[M], W[M], idx;
    bool is_bridge[M];
    int dfn[N], low[N], times;
    int stk[N], top;
    int ans;
    void add(int u, int v, int w) {
        ne[idx] = h[u];
        to[idx] = v;
        W[idx] = w;
        h[u] = idx++;
    }
    int f[N];
    int Find(int x) {return f[x] == x?x:f[x]= Find(f[x]);}
    void un(int i) {
        int x = e[i].u;
        int y = e[i].v;
        int fx = Find(x);
        int fy = Find(y);
        if (fx == fy) {
            return;
        }ans += e[i].w;
        add(x, y, e[i].w);
        add(y, x, e[i].w);
        f[fx]  = fy;
        e[i].choose = 1;
    }
    int dep[N];
    int fa[N][20];
    int ga[N][20];
    void dfs(int u, int father) {
        if (father == -1)dep[u] = 1;
        else dep[u] = dep[father] + 1;
        for (int i = 1; i < 15; i ++) {
            fa[u][i] = fa[fa[u][i-1]][i-1];
            ga[u][i] = max(ga[u][i-1], ga[fa[u][i-1]][i-1]);
        }
        for (int i = h[u]; ~i ;i = ne[i]) {
            int v = to[i];
            if (v != father) {
                fa[v][0] = u;
                ga[v][0] = W[i];
                dfs(v, u);
            }
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v])swap(u, v);
        int Max = -1;
        for (int i = 14; i >= 0; i--) {
            if (dep[fa[u][i]]>=dep[v]) {
                Max = max(Max, ga[u][i]);
                u = fa[u][i];
            }
        }
        if (u == v)return Max;
        for (int i = 14; i >= 0; i--) {
            if (fa[u][i] != fa[v][i]) {
                Max = max(Max, ga[u][i]);
                Max = max(Max, ga[v][i]);
                u = fa[u][i];
                v = fa[v][i];
            }
        }
        Max = max(Max, ga[u][0]);
        Max = max(Max, ga[v][0]);
        return Max;
    }
    void solve() {
        int n, m;
        cin >> n >> m;
        for (int i  =1; i <= n; i ++)f[i] = i;
        memset(h, -1, sizeof h);
        memset(dep, 0, sizeof dep);
        ans = idx = 0;
        for (int i = 1;i <= m;i ++) {
            int u, v, w;cin >> u >> v >> w;
            e[i] = {u, v, w};
            e[i].choose = 0;
        }
        sort(e + 1, e + 1 +  m, cmp);
        for (int i = 1; i <= m; i  ++) {
            un(i);
        }
        dfs(1, -1);
        int ans2  = 99999999;
        for (int i = 1; i <= m; i ++) {
            if (!e[i].choose) {
                ans2 = min(ans2, ans + e[i].w - lca(e[i].u, e[i].v));
            }
        }
        cout << ans <<" " << ans2 << endl;
    }
    signed main() {
        int t;cin >> t;
        while (t--) {
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    文件系统
    Java的日志模块
    SQL Server 的索引结构实例
    SQL索引优化
    索引最佳实践
    SQL优化基础 使用索引(一个小例子)
    v使用索引的注意事项及常见场景、案例
    使用索引的注意事项及常见场景、案例
    SQL性能优化十条经验
    如何使用JVisualVM进行性能分析
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14635682.html
Copyright © 2020-2023  润新知