zoukankan      html  css  js  c++  java
  • HDU 2586 How far away ?【LCA】

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=2586

    题意:

    无向图,给定边及边权重,任意两点之间都有一条唯一的道路,道路上每个点只能出现一次。给定询问,求询问的结点之间的距离。

    分析:

    路上每个点只能出现一次~可以转化成有根树,问题也即为求最近公共祖先问题~~
    这里每条边加上了距离,求出lca后,用u、v的距离根的距离和减去2倍的根到最近公共祖先的距离即可~

    代码:

    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fuck cout<<"fuck"<<endl;
    const int maxn = 40005, maxq = 205;
    typedef pair<int, int>p;
    vector<p>G[maxn];
    #define fi first
    #define se second
    int pa[maxn];
    bool vis[maxn];
    bool in[maxn];
    int ance[maxn];
    int dist[maxn];
    int n, tot;
    int head[maxn];
    int ans[maxn];
    struct Query{int to, next, index;};
    Query query[maxq * 2];
    void add_query(int u, int v, int index)
    {
        query[tot].to = v;
        query[tot].index = index;
        query[tot].next = head[u];
        head[u] = tot++;
        query[tot].to = u;
        query[tot].index = index;
        query[tot].next = head[v];
        head[v] = tot++;
    }
    int _find(int x)
    {
        if(pa[x] != x) return pa[x] = _find(pa[x]);
        return x;
    }
    void unite(int x, int y)
    {
        int rx = _find(x), ry = _find(y);
        if(rx == ry) return;
        pa[rx] = ry;
    }
    void init()
    {
        tot = 0;
       for(int i = 1; i <= n; i++){
            G[i].clear();
            pa[i] = i;
       }
        mem(ance, 0);
        mem(vis, false);
        mem(head, -1);
        mem(dist, 0);
        mem(in, false);
        mem(ans, 0);
    }
    void LCA(int u)
    {
        ance[u] = u;
        vis[u] = true;
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i].fi;
            if(vis[v]) continue;
            dist[v] = dist[u] + G[u][i].se;
            LCA(v);
            unite(u, v);
            ance[_find(u)] = u;
        }
    
        for(int i = head[u]; i != -1; i = query[i].next){
            int v = query[i].to;
            if(vis[v])  ans[query[i].index] = dist[u] + dist[v] - 2 * dist[ance[_find(u)]];
        }
    }
    int main(void)
    {
        int u, v, k;
        int a, b, c;
        int Q;
        int T;scanf("%d", &T);
        while(T--){
            init();
            scanf("%d%d", &n, &Q);
            for(int i = 0; i < n - 1; i++){
                scanf("%d%d%d",&a, &b, &c);
                G[a].push_back(p(b, c));
                G[b].push_back(p(a, c));
            }
            for(int i = 0; i < Q; i++){
               scanf("%d%d",&u,&v);
                add_query(u, v, i);
            }
            dist[1] = 0;
            LCA(1);
            for(int i = 0; i <Q; i++){
                printf("%d
    ", ans[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    poj3718 Facer's Chocolate Dream
    codeforces 917D Stranger Trees
    uoj#349 【WC2018】即时战略
    bzoj5153 [Wc2018]州区划分
    bzoj5152 [Wc2018]通道
    loj2001[SDOI2017]树点染色
    loj2000[SDOI2017]数字表格
    Atcoder arc092
    bzoj4826[hnoi2017]影魔
    bzoj4827 [hnoi2017]礼物
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758695.html
Copyright © 2011-2022 走看看