zoukankan      html  css  js  c++  java
  • AHOI2008 聚会

    题目传送门


    先把每两个点之间的LCA求出来
    画图模拟,显然可以(也可能并不显然)发现集合点选为深度最小的LCA时最优

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define mod 998244353
    #define LL long long
    using namespace std;
    LL read() {
        LL k = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
            k = k * 10 + c - 48, c = getchar();
        return k * f;
    }
    struct zzz {
        int t, nex;
    }e[500010 << 1]; int head[500010], tot;
    void add(int x, int y) {
        e[++tot].t = y;
        e[tot].nex = head[x];
        head[x] = tot;
    }
    int f[500010][32], lg[500010], deth[500010];
    LL len[500010];
    void dfs(int now, int fa) {
        f[now][0] = fa; deth[now] = deth[fa] + 1;
        len[now] = len[fa] + 1;
        for(int i = 1; i <= lg[deth[now]]; ++i)
          f[now][i] = f[f[now][i-1]][i-1];
        for(int i = head[now]; i; i = e[i].nex)
          if(e[i].t != fa) dfs(e[i].t, now);
    }
    int LCA(int x, int y) {
    	//if(x == y) return x;
        if(deth[x] < deth[y]) swap(x, y);
        while(deth[x] > deth[y])
          x = f[x][lg[deth[x]-deth[y]]-1];
        if(x == y) return x;
        for(int i = lg[deth[x]]; i >= 0; --i)
          if(f[x][i] != f[y][i])
            x = f[x][i], y = f[y][i];
        return f[x][0];
    }
    int main() {
        int n = read(), m = read();
        for(int i = 1; i <= n; ++i) lg[i] = lg[i-1] + (1 << lg[i-1] == i);
        for(int i = 1; i <= n-1; ++i) {
            int x = read(), y = read();
            add(x, y); add(y, x);
        }
        deth[0] = -1; dfs(1, 0);
    	for(int i = 1; i <= m; ++i) {
    		int x = read(), y = read(), z = read();
    		int xx = LCA(x, y), yy = LCA(y, z), zz = LCA(x, z), lca;
    		int d = max(deth[xx], max(deth[yy], deth[zz]));
    		if(deth[xx] == d) lca = xx;
    		else if(deth[yy] == d) lca = yy;
    		else lca = zz;
    		LL ans = len[x] + len[y] + len[z] - len[xx] - len[yy] - len[zz];
    		printf("%d %lld
    ", lca, ans);
    	}
    
        return 0;
    }
    
  • 相关阅读:
    SGU438_The Glorious Karlutka River =)
    SGU326_Perspective
    Problem B. Harvest of Apples(莫队+数学)
    【HDU2019多校】1005
    【HDU2019多校】K
    L
    「2017 山东一轮集训 Day2」Pair (霍尔定理+线段树)
    【2017西安】Sum of xor sum(线段树)
    【2017西安】 XOR (线性基+思维)
    【SPOJ】Lightning Conductor (dp+决策单调性)
  • 原文地址:https://www.cnblogs.com/morslin/p/11855673.html
Copyright © 2011-2022 走看看