zoukankan      html  css  js  c++  java
  • HDU 6074

    看标程的代码这么短,看我的....

    难道是静态LCA模板太长了? 

    /*
    HDU 6074 - Phone Call [ LCA,并查集 ]  |  2017 Multi-University Training Contest 4
    题意:
    	给一棵树,定义集合S(u,v)为u到v路径上所有的点
    	给出 m 个 <S(u1,v1)|S(u2,v2) , w > ,意思为集合里面的点互相距离为 w 
    	求 1 能到的所有点和该生成树的最小权值
    分析:
    	将所有线路按代价从小到大排序,对于每条线路(a,b,c,d)
    		分别把S(a,b)和S(c,d)合并到 LCA,最后再把两个 LCA 合并即可
    	再用f(i)表示i向上第一个与i不在同一个连通块的点, 就可用并查集压缩路径
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int N = 100005;
    const int Q = 200005;
    vector<int> G[N];
    namespace LCA{
        struct Query {
            int v, q;
        }; vector <Query> query[N];
        int ans[Q], f[N], vis[N];
        int sf(int x) {
            return x == f[x] ? x : f[x] = sf(f[x]);
        }
        void init() {
            memset(ans, -1, sizeof(ans));
            for (int i = 0; i < N; i++) {
                vis[i] = 0;
                f[i] = i;
                query[i].clear();
            }
        }
        void adq(int u, int v, int id) {
            query[u].push_back(Query{v, id});
            query[v].push_back(Query{u, id});
        }
        void LCA(int u) {
            f[u] = u;
            vis[u] = 1;
            for (auto& x : query[u]) {
                if (vis[x.v] && ans[x.q] == -1)
                    ans[x.q] = sf(x.v);
            }
            for (auto& v : G[u]) {
                if (vis[v]) continue;
                LCA(v);
                f[v] = u;
            }
        }
    }
    int pre[N];
    void dfs(int u, int fa) {
        pre[u] = fa;
        for (auto v : G[u]) {
            if (v == fa) continue;
            dfs(v, u);
        }
    }
    int f[N], num[N];
    LL res[N];
    int sf(int x){
        return x == f[x] ? x : f[x] = sf(f[x]);
    }
    int same[N];
    int Same(int x) {
        return x == same[x] ? x : same[x] = Same(same[x]);
    }
    int w;
    void join(int a, int b){
        a = sf(a), b = sf(b);
        if (a == b) return;
        f[b] = a;
        num[a] += num[b];
        res[a] += res[b] + w;
    }
    struct Node {
        int a1, b1, a2, b2, w;
        int c1, c2;
    }e[N];
    bool cmp(Node a, Node b) {
        return a.w < b.w;
    }
    void solve(int a, int fa) {
        while (Same(a) != Same(fa)) {
            a = Same(a);
            join(pre[a], a);
            same[a] = pre[a];
        }
    }
    int t, n, m;
    int main() {
        scanf("%d", &t);
        while (t--) {
            for (int i = 0; i < N; i++) G[i].clear();
            LCA::init();
            scanf("%d%d", &n, &m);
            for (int i = 1; i < n; i++) {
                int u, v; scanf("%d%d", &u, &v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            int Q = 0;
            for (int i = 1; i <= m; i++) {
                scanf("%d%d%d%d%d", &e[i].a1, &e[i].b1, &e[i].a2, &e[i].b2, &e[i].w);
                e[i].c1 = ++Q;
                LCA::adq(e[i].a1, e[i].b1, Q);
                e[i].c2 = ++Q;
                LCA::adq(e[i].a2, e[i].b2, Q);
            }
            LCA::LCA(1);
            for (int i = 1; i <= m; i++) {
                e[i].c1 = LCA::ans[e[i].c1];
                e[i].c2 = LCA::ans[e[i].c2];
            }
            dfs(1, 1);
            sort(e+1, e+m+1, cmp);
            for (int i = 1; i <= n; i++) {
                f[i] = same[i] = i;
                num[i] = 1;
                res[i] = 0;
            }
            for (int i = 1; i <= m; i++) {
                w = e[i].w;
                solve(e[i].a1, e[i].c1);
                solve(e[i].b1, e[i].c1);
                solve(e[i].a2, e[i].c2);
                solve(e[i].b2, e[i].c2);
                join(e[i].c1, e[i].c2);
            }
            printf("%d %lld
    ", num[sf(1)], res[sf(1)]);
        }
    }
    

      

  • 相关阅读:
    1002. 查找常用字符『简单』
    1108. IP 地址无效化『简单』
    1137. 第 N 个泰波那契数『简单』
    1154. 一年中的第几天『简单』
    1185. 一周中的第几天『简单』
    1207. 独一无二的出现次数『简单』
    暑期集训模拟赛3
    暑期集训模拟赛2
    暑期集训模拟赛1
    CF526F Pudding Monsters 【分治】
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7301983.html
Copyright © 2011-2022 走看看