zoukankan      html  css  js  c++  java
  • [bzoj] Network

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

    /*
        Kruskal 最小生成树
        树链剖分 最大值查询
        注意:可能会有几块不联通的图
    */
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    
    using namespace std;
    const int N = 25010;
    
    #define gc getchar()
    #define lson jd << 1
    #define rson jd << 1 | 1 
    
    int n, m, k, now = 1, tim, ans;
    int bef[N], data[N], fat[N], head[N], tree[N], topp[N], fa[N], son[N], siz[N], deep[N];
    struct Node_1{int u, v, w;} E[N << 1];
    struct Node_2{int u, v, w, nxt;} G[N << 2];
    struct Node_3{int l, r, Max;} T[N << 2];
    
    bool cmp(Node_1 a, Node_1 b) {return a.w < b.w;}
    
    struct Bzoj_3732{
        
        inline int read(){
            int x = 0; char c = gc;
            while(c < '0' || c > '9') c = gc;
            while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
            return x;
        }
        
        inline int getf(int x) {return fat[x] == x ? x : fat[x] = getf(fat[x]);}
        inline void add(int u, int v, int w) {G[now].v = v; G[now].w = w; G[now].nxt = head[u]; head[u] = now ++;}
        
        inline void Kruskal(){
            int js(0);
            for(int i = 1; i <= m; i ++){
                int u = E[i].u, v = E[i].v;
                int fu = getf(u), fv = getf(v);
                if(fu != fv) {
                    js ++; fat[fu] = fv; 
                    add(u, v, E[i].w); 
                    add(v, u, E[i].w);
                }
                if(js == n - 1) return ;
            }
        }
        
        void dfs_find_son(int u, int f_, int dep){
            fa[u] = f_;
            deep[u] = dep;
            siz[u] = 1;
            for(int i = head[u]; ~ i; i = G[i].nxt){
                int v = G[i].v;
                if(v != f_){
                    data[v] = G[i].w;
                    dfs_find_son(v, u, dep + 1);
                    siz[u] += siz[v];
                    if(siz[v] > siz[son[u]]) son[u] = v;
                }
            }
        }
         
        void dfs_to_un(int u, int tp){
            topp[u] = tp;
            tree[u] = ++ tim;
            bef[tim] = u;
            if(!son[u]) return ;
            dfs_to_un(son[u], tp);
            for(int i = head[u]; ~ i; i = G[i].nxt){
                int v = G[i].v;
                if(v != fa[u] && v != son[u]) dfs_to_un(v, v);
            }
        }
        
        void build_tree(int l, int r, int jd){
            T[jd].l = l; T[jd].r = r;
            if(l == r) {T[jd].Max = data[bef[l]]; return ;}
            int mid = (l + r) >> 1;
            build_tree(l, mid, lson);
            build_tree(mid + 1, r, rson);
            T[jd].Max = max(T[lson].Max, T[rson].Max);
        }
        
        void Sec_A(int l, int r, int jd, int x, int y){
            if(x <= l && r <= y) {ans = max(ans, T[jd].Max); return ;}
            int mid = (l + r) >> 1;
            if(x <= mid) Sec_A(l, mid, lson, x, y);
            if(y > mid)  Sec_A(mid + 1, r, rson, x, y);
        }
        
        inline int Sec_A_imp(int x, int y){
            int tp1 = topp[x], tp2 = topp[y], ret = 0;
            while(tp1 != tp2){
                if(deep[tp1] < deep[tp2]) swap(x, y), swap(tp1, tp2);
                ans = 0;
                Sec_A(1, n, 1, tree[tp1], tree[x]);
                ret = max(ans, ret);
                x = fa[tp1];
                tp1 = topp[x];
            }
            if(x == y) return ret;
            if(deep[x] < deep[y]) swap(x, y);
            ans = 0;
            Sec_A(1, n, 1, tree[y] + 1, tree[x]);
            ret = max(ret, ans);
            return ret;
        }
    }AC;
    
    int main()
    {
        n = AC.read(), m = AC.read(); k = AC.read();
        for(int i = 1; i <= n; i ++) fat[i] = i, head[i] = -1;
        for(int i = 1; i <= m; i ++)
            E[i].u = AC.read(), E[i].v = AC.read(), E[i].w = AC.read();
        sort(E + 1, E + m + 1, cmp);
        AC.Kruskal();
        for(int i = 1; i <= n; i ++) if(!deep[i]) AC.dfs_find_son(i, 0, 1);
        for(int i = 1; i <= n; i ++) if(!topp[i]) AC.dfs_to_un(i, i);
        AC.build_tree(1, n, 1);
        while(k --){
            int x = AC.read(), y = AC.read();
            int Answer = AC.Sec_A_imp(x, y);
            printf("%d
    ", Answer);
        }
        
        return 0;
    }

     与noip2013货车运输相似(一模一样)

    货车运输:最大生成树 + 最小值查询

    此题       :最小生成树 + 最大值查询

    货车运输改几行代码就A了

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <string>
    
    using namespace std;
    const int N = 15010;
    
    #define oo 99999999
    
    struct Node{
        int u, v, w;
    }S[N << 1];
    struct Edge{
        int u, v, w, nxt;
    }E[N << 2];
    
    int now = 1, n, m, js;
    int head[N], p[N], f[N][30], g[N][30], deep[N];
    
    inline int read(){
        int x = 0; char c = getchar();
        while(c < '0' || c > '9') c = getchar();
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x; 
    }
    
    inline bool cmp(Node a, Node b){
        return a.w < b.w;
    }
    
    int getf(int x){
        return p[x] == x ? x : p[x] = getf(p[x]); 
    }
    
    void add(int u, int v, int w){
        E[now].v = v;
        E[now].w = w;
        E[now].nxt = head[u];
        head[u] = now ++;
    }
    
    inline void Kruskal(){
        for(int i = 1, doen = 1; i <= (m << 1) && doen < n; i ++){
            int u = S[i].u, v = S[i].v;
            int pu = getf(u), pv = getf(v);
            if(pu != pv){
                p[pu] = pv;
                add(u, v, S[i].w);
                add(v, u, S[i].w);
                doen ++;
            } 
        }
    }
    
    void make_deep(int u, int depth){
        deep[u] = depth;
        for(int i = head[u]; ~ i; i = E[i].nxt){
            int v = E[i].v;
            if(!deep[v]){
                f[v][0] = u;
                g[v][0] = E[i].w;
                make_deep(v, depth + 1);
            } 
        }
    }
    
    inline void make_jump(){
        for(int j = 1; (1 << j) <= n; j ++)
            for(int i = 1; i <= n; i ++)
                if(f[i][j - 1]) f[i][j] = f[f[i][j - 1]][j - 1], g[i][j] = max(g[i][j - 1], g[f[i][j - 1]][j - 1]);
    }
    
    inline int lca(int x, int y){
        int ret = -1;
        if(x == y) return 0;
        if(deep[x] < deep[y]) swap(x, y);
        int k = log2(deep[x]);
        for(int i = k; i >= 0; i --){
            if(deep[f[x][i]] >= deep[y]){
                ret = max(ret, g[x][i]);
                x = f[x][i];
            }
        }
        if(x == y) return ret;
        for(int i = k; i >= 0; i --){
            if(f[x][i] != f[y][i]){
                ret = max(ret, max(g[x][i], g[y][i]));
                x = f[x][i];
                y = f[y][i];
            }
        }
        ret = max(ret, max(g[x][0], g[y][0]));
        return ret;
    }
    
    int main()
    {
        n = read();
        m = read();
        int T = read();
        for(int i = 1; i <= n; i ++) head[i] = -1, p[i] = i;
        for(int i = 1; i <= m; i ++) S[i].u = read(), S[i].v = read(), S[i].w = read();
        sort(S + 1, S + m + 1, cmp);
        Kruskal();
        for(int i = 1; i <= n; i ++) if(!deep[i]) make_deep(i, 1);//可能会有多块 
        make_jump();
        while(T --){
            int x = read(), y = read();
            int answer = lca(x, y);
            printf("%d
    ", answer);
        }
        return 0; 
    }
  • 相关阅读:
    poj 1050
    poj 2479 Maximum sum
    Trie树结构(AC自动机前奏)(转)
    poj 3624(zeroonepack)
    poj 3630(Phone List )
    KMP算法(AC自动机前奏)(转)
    AC自动机(转)
    AC自动机模板(hdu2222)
    Running CMD.EXE as Local System
    什么是WPF(Avalon)
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8215484.html
Copyright © 2011-2022 走看看