长大校赛G(树的直径+图论)

看错题意以为这题不可做。。其实傻逼得很qaq

距离和一定,要使访问的点最多,最显然的办法是走成一条链。。那么就要找离该点距离最大的点,而这个点显然是直径端点,为此需要先求出直径。。。

然后距离和可能会比链长还要再长,即我们还可以访问更多的点,在这链的基础之上,每多访问一个点的代价是2(以链上一点向外延伸一个小分支,这个小分支还有来回,在这个分支的基础上再延伸也是2),那么把剩余的距离除以2就可以得出还可以访问的点了。。

当然点数肯定不能超过n,记得特判即可。。。





/**
 *        ┏┓    ┏┓
 *        ┏┛┗━━━━━━━┛┗━━━┓
 *        ┃       ┃  
 *        ┃   ━    ┃
 *        ┃ >   < ┃
 *        ┃       ┃
 *        ┃... ⌒ ...  ┃
 *        ┃       ┃
 *        ┗━┓   ┏━┛
 *          ┃   ┃ Code is far away from bug with the animal protecting          
 *          ┃   ┃   神兽保佑,代码无bug
 *          ┃   ┃           
 *          ┃   ┃        
 *          ┃   ┃
 *          ┃   ┃           
 *          ┃   ┗━━━┓
 *          ┃       ┣┓
 *          ┃       ┏┛
 *          ┗┓┓┏━┳┓┏┛
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛
 */ 
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-12
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 100005
#define nm 200005
#define pi 3.1415926535897931
using namespace std;
const ll inf=998244353;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}



struct edge{int t;edge*next;}e[nm],*h[NM],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}

int n,m,d[NM],b[NM],f[NM],_x,_y;
void dfs(int x){
	link(x)if(!f[j->t]){
		f[j->t]=x;d[j->t]=d[x]+1;
		dfs(j->t);
	}
}

int main(){
	int _=read();
	while(_--){
		n=read();mem(d);mem(f);mem(e);mem(h);o=e;
		inc(i,1,n-1){_x=read();_y=read();add(_x,_y);add(_y,_x);}
		dfs(f[1]=1);_x=_y=1;
		inc(i,1,n)if(d[i]>d[_x])_x=i;
		mem(f);mem(d);dfs(f[_x]=_x);
		inc(i,1,n)b[i]=d[i];
		inc(i,1,n)if(d[i]>d[_y])_y=i;
		mem(f);mem(d);dfs(f[_y]=_y);
		m=read();
		while(m--){
			int x=read(),t=read();
			if(d[x]>b[x])printf("%d\n",d[x]<t?min(n,d[x]+1+(t-d[x])/2):t+1);
			else printf("%d\n",b[x]<t?min(n,b[x]+1+(t-b[x])/2):t+1);
		}
	}
	return 0;
}





链接:https://www.nowcoder.com/acm/contest/102/G
来源:牛客网
Go For Travel

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

There are n cities in the Rainbow Island, connected by n−1 bidirectional roads.
Lizishu is fond of travel. In the i th of each m years, she would go for travel from city x i with k i Yuan and she would cost 1 Yuan leaving a city to an adjacent one. For seeing more scenery, she wants to go to as many  different cities as possible.
Now you are given the map of the Rainbow Island and you should tell Lizishu the maximum number of different cities (including x i) she can reach every year.
Note that every time she can only go to an adjacent city and cost 1 Yuan.

输入描述:

The first line contains an integer number T, the number of test cases.
For each test case :
The first line contains an integer n(1 ≤ n ≤ 105), the number of vertices.
The following n−1 lines, each contains two integers u,v(1 ≤ u,v ≤ n), which means there is an edge between u and v.
It is guaranteed that the graph is connected.
The next line contains an integer m(1 ≤ m ≤ 106), the number of years.
The following m lines, the ith line contains two integers xi(1 ≤ xi≤ n),ki(1 ≤ ki≤ 106), the index of the city she starts travel and the money she carries in the ith year.

输出描述:

For each year print the answer.
示例1

输入

1
6
1 2
1 3
2 4
2 5
3 6
2
2 2
2 4

输出

3
4

猜你喜欢

转载自blog.csdn.net/qkoqhh/article/details/79951083