zoukankan      html  css  js  c++  java
  • ACM Contest and Blackout UVA

    原题链接

    • 题解:求非严格次小生成树,先钦定一个最小生成树,枚举每一条非树边。可发现加入枚举的这条边,定能成环,然后再在环上断开最大的是树边的一条边,然后枚举取最小值。为了缩小时间瓶颈,用了倍增法,预处理最小生成树上两个点之间到最近公共祖先的路上最长的边长,然后 (log) 复杂度的查询。
    • 代码:
    #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;
    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;
    }
    
  • 相关阅读:
    确保消息产生前数据库操作已提交
    信息披露和公司简介总结
    1、清空所有,给当前添加/2、清空上一个,给当前添加。
    不能作为判断条件的:
    excel表格 函数功能
    一种ui app写法
    正则中使用变量及数组去重的方法
    鼠标锁定(消失),进入无限滚动状态
    transform 的旋转 ,3d效果,要添加3d效果的父级加上景深perspective。 3d效果的容器加上 transform-style:preserve-3d。
    rem布局,在用户调整手机字体大小/用户调整浏览器字体大小后,布局错乱问题
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14635677.html
Copyright © 2011-2022 走看看