zoukankan      html  css  js  c++  java
  • bzoj 3732: Network 树上两点边权最值

    http://www.lydsy.com/JudgeOnline/problem.php?id=3732

    首先想到,要使得最长边最短,应该尽量走最短的边,在MST上。

    然后像LCA那样倍增娶个最大值

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int maxn = 30000 + 20;
    struct Edge {
        int u, v, w, tonext;
        bool operator < (const struct Edge & rhs) const {
            return w < rhs.w;
        }
    } e[maxn], t[maxn];
    int first[maxn], num;
    void addEdge(int u, int v, int w) {
        e[num].u = u, e[num].v = v, e[num].w = w, e[num].tonext = first[u];
        first[u] = num++;
    }
    int tfa[maxn];
    int tofind(int u) {
        if (tfa[u] == u) return u;
        else return tfa[u] = tofind(tfa[u]);
    }
    const int need = 20;
    int mx[maxn][25];
    int ansc[maxn][25], deep[maxn], fa[maxn];  //所有只需初始值,不需要初始化。
    void init_LCA(int cur) {   //1 << 20就有1048576(1e6)了。
        ansc[cur][0] = fa[cur]; //跳1步,那么祖先就是爸爸
        if (cur != 1) {
            for (int i = first[fa[cur]]; ~i; i = e[i].tonext) {
                int v = e[i].v;
                if (v == cur) {
                    mx[cur][0] = e[i].w;
                    break;
                }
            }
        }
        int haha = mx[cur][0];
        for (int i = 1; i <= need; ++i) { //倍增思路,递归处理
            ansc[cur][i] = ansc[ansc[cur][i - 1]][i - 1];
            mx[cur][i] = mx[ansc[cur][i - 1]][i - 1];
            mx[cur][i] = max(mx[cur][i], haha);
            haha = max(haha, mx[cur][i]);  //上到极限的时候需要取个路经的最大值。
        }
        for (int i = first[cur]; ~i; i = e[i].tonext) {
            int v = e[i].v;
            if (v == fa[cur]) continue;
            fa[v] = cur;
            deep[v] = deep[cur] + 1;
            init_LCA(v);
        }
    }
    int LCA(int x, int y) {
        int res = 0;
        if (deep[x] < deep[y]) swap(x, y); //需要x是最深的
        for (int i = need; i >= 0; --i) { //从大到小枚举,因为小的更灵活
            if (deep[ansc[x][i]] >= deep[y]) { //深度相同,走进去就对了。就是要去到相等。
                res = max(res, mx[x][i]);
                x = ansc[x][i];
            }
        }
        if (x == y) return res;
        for (int i = need; i >= 0; --i) {
            if (ansc[x][i] != ansc[y][i]) { //走到第一个不等的地方,
                res = max(res, mx[x][i]);
                res = max(res, mx[y][i]);
                x = ansc[x][i];
                y = ansc[y][i];
            }
        }
        res = max(res, mx[x][0]);
        res = max(res, mx[y][0]);
        return res; //再跳一步就是答案
    }
    
    
    void work() {
        num = 0;
        memset(first, -1, sizeof first);
        int n, m, k;
        scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= n; ++i) tfa[i] = i;
        for (int i = 1; i <= m; ++i) {
            scanf("%d%d%d", &t[i].u, &t[i].v, &t[i].w);
        }
        sort(t + 1, t + 1 + m);
        int sel = 0;
        for (int i = 1; i <= m; ++i) {
            if (sel == n - 1) break;
            int x = tofind(t[i].u), y = tofind(t[i].v);
            if (x == y) continue;
            sel++;
            tfa[y] = x;
            addEdge(t[i].u, t[i].v, t[i].w);
            addEdge(t[i].v, t[i].u, t[i].w);
        }
        fa[1] = 1, deep[1] = 0;
        init_LCA(1);
    //    printf("%d
    ", mx[2][1]);
        for (int i = 1; i <= k; ++i) {
            int u, v;
            scanf("%d%d", &u, &v);
            printf("%d
    ", LCA(u, v));
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7392488.html
Copyright © 2011-2022 走看看