Technology Tree

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bingongzi/article/details/84895265

链接:https://ac.nowcoder.com/acm/contest/303/K
来源:牛客网
 

题目描述

在星际争霸(StarCraft)中,有3个种族。对于任意一个种族,他们的建筑建造都是有一个顺序的。这个顺序正好是一个树形结构,我们称之为"科技树"(Technology tree)。

在科技树中,只有一个建筑是不需要前置建筑的,我们把这个建筑的编号设为1。其他的建筑,有且仅有一个前置建筑。

比如建筑2的前置建筑为建筑1,意思是只有先建造了建筑1,才能建造建筑2。

一个种族有n个建筑,建筑1没有前置建筑,建筑i(2≤i≤n)的前置建筑为f。每个建筑的建造都需要费用,建筑i(1≤i≤n)的建造花费为a晶体矿和b高能瓦斯。

现在tokitsukaze想知道,如果想要建造建筑x,总共需要消耗多少晶体矿和高能瓦斯。

输入描述:

第一行包含一个T(T≤10),表示T组数据。

对于每组数据:
第一行包含两个正整数n,q(1≤n,q≤20000),表示有n个建筑和q次查询。
接下来n行,每行包含两个整数a,b(0≤a,b≤300),表示建造建筑i需要花费a晶体矿和b高能瓦斯。
接下来一行,包含n-1个正整数f(1≤f≤n)。第i个(1≤i<n)正整数fi(1≤fi<i)表示建筑i+1的前置建筑为fi。
接下来q行,每行包含一个正整数x,表示询问。

输出描述:

对于每个询问,输出一行,包含两个整数c,d(用空格隔开),表示如果想要建造建筑x,总共需要消耗c晶体矿和d高能瓦斯。

示例1

输入

复制

1
4 4
1 5
10 100
200 50
66 88
1 1 2
1
2
3
4

输出

复制

1 5
11 105
201 55
77 193

说明

第一组样例:

如果想要建造建筑1,总共需要消耗1晶体矿和5高能瓦斯。

如果想要建造建筑2,需要先建造建筑1,总共需要消耗1+10晶体矿和5+100高能瓦斯。
如果想要建造建筑3,需要先建造建筑1,总共需要消耗1+200晶体矿和5+50高能瓦斯。
如果想要建造建筑4,需要先建造建筑1和建筑2,总共需要消耗1+10+66晶体矿和5+100+88高能瓦斯。

分析:题意大概就是要求出各点到1所需要的时间(包括1本身)。

代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
	int i,t,n,m,q,a[20010],b[20010],f[20010],dis1[20010],dis2[20010],x;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&q);
		memset(dis1,0,sizeof(dis1));
		memset(dis2,0,sizeof(dis2));
		for(i=1;i<=n;i++)
		{
			scanf("%d%d",&a[i],&b[i]);
		}
		for(i=1;i<=n-1;i++)
		{
			scanf("%d",&f[i]);
			dis1[i+1]=dis1[f[i]]+a[i+1];//计算i+1到1之间需要的晶体矿 
			dis2[i+1]=dis2[f[i]]+b[i+1];//计算i+1到1之间需要的高能瓦斯 
		}
		while(q--)
		{
			scanf("%d",&x);
			printf("%d %d\n",dis1[x]+a[1],dis2[x]+b[1]);//计算结果加上1本身 
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/bingongzi/article/details/84895265