zoj 2684 ChonSu

ChonSu

Time Limit: 2 Seconds      Memory Limit: 65536 KB

The genealogy of a family can be represented as a rooted tree, in which each node corresponds to a member of the family, and each edge connects a member to his/her parent. The root is the founder of the family and has no parent in the genealogy; leaf nodes correspond to those with no child. The distance between two members in a genealogy is called a ChonSu in Korea, which is defined as the number of edges on the path between them. For example, in the genealogy shown below, the ChonSu between persons 1 and 3 is 3 while the ChonSu between persons 1 and 5 is 5. From now on, the ChonSu between person i and person j will be denoted by ChonSu(i, j).

A rooted tree in which each node, unless it is a leaf node, has exactly two children is a 2-tree. In other words, a 2-tree is a binary tree in which each node has either two children or none. For example, the tree shown above is a 2-tree.

Consider a family whose complete genealogy is unknown. What is known about the genealogy of the family is that it is a 2-tree and it has n leaf nodes. Assume that the leaf nodes are numbered from 1, 2, ... , n in the left-to-right order as shown in the figure above. Also known about the genealogy is the ChonSu between every pair of leaf nodes whose numbers are consecutive; i.e., ChonSu(i, i+1) for every i(1 <= i <= n-1) is known.

It is well known that only from the information about the family given above, the ChonSu between any two leaf nodes can be computed.

You are to write a program to compute the ChonSu between two leaf members x, y (1 <= x < y <= n) given as an input.

For the example above, you are given as input, n = 6, ChonSu(1, 2) = 3, ChonSu(2, 3) = 2, ChonSu(3, 4) = 5, ChonSu(4, 5) = 3, and ChonSu(5, 6) = 2. From this information, you can compute ChonSu(1, 6), that is, the ChonSu between x = 1 and y = 6.

Input

The input consists of T test cases. The number of test cases (T) is given on the first line of the input file. The first line of each test case contains an integer n (3 <= n <= 1000), the number of leaf nodes. The next line contains a sequence of n ? 1 integers which are ChonSu(1, 2), ChonSu(2, 3), ... , ChonSu(n - 1, n). The last line of each test case contains two distinct integers x, y (1 <= x < y <= n) which are the numbers of the two leaf members between whom the ChonSu is to be computed.

Output

Print exactly one line for each test case. The line is to contain an integer that is the ChonSu between two leaf nodes. The following shows sample input and output for two test cases.

Sample Input

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

Sample Output

5
5


分析:每次选取距离为2的点,向上建树。使用list来维护距离

#include<cstdio>
#include<cstring>
#include<list>
using namespace std;
const int N=2005;
struct node{
	int l,r,va;
}t;
list<node> L;
list<node>::iterator it,l,r;
int p[N],d[N];
bool v[N];
int main(){
	int T,n,i,k,x,y;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);k=n;
		L.clear();
		for(i=1;i<n;i++){
			t.l=i,t.r=i+1;
			scanf("%d",&t.va);
			L.push_back(t);
		}
		memset(p,0,sizeof(p));
		for(it=L.begin();it!=L.end();){
			if((*it).va==2){
				++k;
				p[(*it).l]=p[(*it).r]=k;
				r=it,r++;
				if(r!=L.end())(*r).va--,(*r).l=k;
				if(it!=L.begin())l=--it,(*l).va--,(*l).r=k;
				else it++;
				L.erase(--r);
			}else it++;
		}
		scanf("%d%d",&x,&y);
		memset(v,0,sizeof(v));
		k=0;
		while(x)v[x]=1,d[x]=k++,x=p[x];
		int ans=0;
		while(y){
			if(v[y])break;
			ans++,y=p[y];
		}
		printf("%d\n",ans+d[y]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值