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

Codeforces Round #294 (Div. 2)

时间:2015-03-04 14:41:14      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:

A

简单题

B

简单题

C

简单题

D

简单题

一棵树 给你2个点 求树上有多少个点到这两个点的距离相等

LCA倍增法

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int anc[maxn][20];
int fa[maxn], L[maxn], sum[maxn];
int n;
int first[maxn], cnt;
struct edge
{
	int u, v, next;
}e[maxn*2];

void AddEdge(int u, int v)
{
	e[cnt].v = v;
	e[cnt].next = first[u];
	first[u] = cnt++;
	e[cnt].v = u;
	e[cnt].next = first[v];
	first[v] = cnt++;
}

void pre()
{
	for(int i = 1; i <= n; i++)
	{
		anc[i][0] = fa[i];
		for(int j = 1; (1<<j) < n; j++)
			anc[i][j] = -1;
	}
	for(int j = 1; (1<<j) < n; j++)
		for(int i = 1; i <= n; i++)
			if(anc[i][j-1] != -1)
			{
				int a = anc[i][j-1];
				anc[i][j] = anc[a][j-1];
			}
	
}

int query(int p, int q)
{
	int log;
	if(L[p] < L[q])
		swap(p, q);
	for(log = 1; (1<<log) <= L[p]; log++);
	log--;
	
	for(int i = log; i >= 0; i--)
		if(L[p] - (1<<i) >= L[q])
		{
			p = anc[p][i];
		}
	if(p == q)
		return p;
	for(int i = log; i >= 0; i--)
	{
		if(anc[p][i] != -1 && anc[p][i] != anc[q][i])
		{
			p = anc[p][i];
			q = anc[q][i];
		}
	}
	if(p != q)
		p = anc[p][0];
	return p;
}
int getkth(int u, int k)
{
	int log;
	for(log = 1; (1<<log) <= k; log++);
	log--;
	
	for(int i = log; i >= 0; i--)
		if(k >= (1<<i))
		{
			k -= (1<<i);
			u = anc[u][i];
		}
	return u;
}
void dfs(int u, int f)
{
	fa[u] = f;
	sum[u] = 1;
	for(int i = first[u]; i != -1; i = e[i].next)
	{
		int v = e[i].v;
		if(v == f)
			continue;
		
		L[v] = L[u]+1;
		dfs(v, u);
		sum[u] += sum[v];
	}
}
int main()
{
	memset(first, -1, sizeof(first));
	cnt = 0;
	scanf("%d", &n);
	for(int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d %d", &u, &v);
		AddEdge(u, v);		
	}
	L[1] = 0;
	dfs(1, -1);
	pre();
	int q;
	scanf("%d", &q);
	while(q--)
	{
		int u, v;
		scanf("%d %d", &u, &v);
		if(u == v)
		{
			printf("%d\n", n);
			continue;
		}
		int rt = query(u, v);
		int d = L[u] + L[v] - 2*L[rt];
		if(d%2)
		{
			printf("%d\n", 0);
			continue;
		}
		if(L[u] == L[v])
		{
			u = getkth(u, d/2-1);
			v = getkth(v, d/2-1);
			printf("%d\n", n-sum[u]-sum[v]);
		}
		else
		{
		
			if(L[u] < L[v])
				swap(u, v);
			v = getkth(u, d/2-1);
			u = getkth(u, d/2);
			printf("%d\n", sum[u]-sum[v]);
		}
	}
	return 0;
}



Codeforces Round #294 (Div. 2)

标签:

原文地址:http://blog.csdn.net/u011686226/article/details/44059753

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