码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 519E A and B and Lecture Rooms LCA

时间:2015-03-03 23:42:20      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接

题意:

给定n个点的树。

下面n-1行给出树

Q个询问。

每次询问 (u,v)问树上有多少个点到u点距离=到v点距离

思路:

首先这两个点的距离必须是偶数,若为奇数答案就是0

然后用lca找到中间节点即可。

trick : u==v ans = n

#include"cstdio"
#include"iostream"
#include"queue"
#include"algorithm"
#include"set"
#include"queue"
#include"cmath"
#include"string.h"
#include"vector"
using namespace std;
template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0;
    while (c != '-' && (c<'0' || c>'9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
template <class T>
inline void pt(T x) {
    if (x <0) {
        putchar('-');
        x = -x;
    }
    if (x>9) pt(x / 10);
    putchar(x % 10 + '0');
}
#define N 100500
struct Edge{
    int from, to, nex;
}edge[2 * N];
int head[N], edgenum, fa[N][20], dep[N], siz[N];  //fa[i][x] 是i的第2^x个父亲(如果超过范围就是根)
void add(int u, int v){
    Edge E = { u, v, head[u] };
    edge[edgenum] = E;
    head[u] = edgenum++;
}
void bfs(int root){
    queue<int> q;
    fa[root][0] = root; dep[root] = 0; siz[root] = 0;
    q.push(root);
    while (!q.empty()){
        int u = q.front(); q.pop();
        for (int i = 1; i<20; i++)fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; ~i; i = edge[i].nex){
            int v = edge[i].to; if (v == fa[u][0])continue;
            dep[v] = dep[u] + 1; fa[v][0] = u;
            q.push(v);
        }
    }
}
void dfs(int u, int f){
    siz[u] = 1;
    for (int i = head[u]; ~i; i = edge[i].nex){
        int v = edge[i].to; if (v == f)continue;
        dfs(v, u);
        siz[u] += siz[v];
    }
}
int Lca(int x, int y){
    if (dep[x]<dep[y])swap(x, y);
    for (int i = 0; i<20; i++)if ((dep[x] - dep[y])&(1 << i))x = fa[x][i];
    if (x == y)return x;
    for (int i = 19; i >= 0; i--)if (fa[x][i] != fa[y][i])x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}
void init(){ memset(head, -1, sizeof head); edgenum = 0; }

int n, m;
int go(int D, int x){
    while (D){
        int z = log10(1.0*D) / log10(2.0);
        x = fa[x][z];
        D -= 1 << z;
    }
    return x;
}
int main(){
    rd(n);
    init();
    for (int i = 1, u, v; i < n; i++){
        rd(u); rd(v);
        add(u, v); add(v, u);
    }
    bfs(1);
    dfs(1, 1);
    rd(m);
    int x, y;
    while (m--){
        rd(x); rd(y);
        if (x == y){ pt(n); putchar('\n'); continue; }
        if (dep[x]>dep[y])swap(x, y);
        int l = Lca(x, y);
        int len = dep[x] - dep[l] + dep[y] - dep[l];
        if (len & 1){
            putchar('0');
        }
        else {
            len = len / 2 - 1;
            int a = go(len, y), b = fa[a][0];
            if (b == l){
                pt(n - siz[a] - siz[go(len, x)]);
            }
            else pt(siz[b] - siz[a]);
        }
        putchar('\n');
    }
    return 0;
}


Codeforces 519E A and B and Lecture Rooms LCA

标签:

原文地址:http://blog.csdn.net/qq574857122/article/details/44046087

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!