Gym - 100814D Frozen Rivers

In winter, all small rivers of Al-Asi great river in Syria are frozen. But when spring comes back they start to melt. These small rivers are connected to each other exactly like a tree, each river (direct edge in the tree) has a value equal to the amount of ice in it.

Here is the tree of the sample test case:

When rivers start to melt, water starts to flow from node 1 (root of the tree) to any node that it can reach. When the water first reaches a node u, ice starts to melt in all its direct children edges at a rate of 1 unit per second. Once (u, v) edge completely melted, the rate of melting of all other edges that start from u will slow down to be 0.5 unit per second, while the other edges that start from v start melting with 1 unit per second.

Given the rivers tree, and a certain time, can you tell us how many leaves of the tree did the water reach? A leaf is a node that has no children.

Input

The first line contains T the number of test cases. For each test case, the first line contains N the number of nodes (2 ≤ N ≤ 100, 000). Followed by N - 1 lines, each line describes the nodes 2 to N. Each line will contain 2 integers Pi and Ci (1  ≤  Pi ≤ N) (0  ≤  Ci  ≤  100,000) representing the parent of the i-th node (i starts from 2 here) and the amount of ice in the edge connecting the current node to its parent. Node 1 is the root of the tree. After that there is a line contains (1 ≤ Q ≤ 100, 000), the number of queries. Then Q lines contain the times of these queries in seconds (0 ≤  query time  ≤ 1012).

Output

Print one line for each query in each test case, this line should contain the number of leaves that the water reached at the time of the query.

Example
Input
1
4
1 3
1 5
2 2
8
1
2
3
4
5
6
7
8
Output
0
0
0
0
1
1
2
2
Note

In the sample test case:

At time 0: water is at node 1

At time 1: water has melted 1 unit of edge (1, 2), and 1 unit of edge (1, 3)

At time 3: water has completely melted edge (1, 2). The rate of melting of (1, 3) drops to 0.5 unit/second, while edge (2, 4) starts to melt at rate 1 unit/second.

At time 5: water has completely melted edge (2, 4), and the remaining edge (1, 3) has 4 units melted, 1 to go.

At time 7: Ice completely melted in all edges.


#include<iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
const ll INF=0x3f3f3f3f;
vector<int>G[maxn];//注意maxn根据题意取值
int nu;
ll tem[maxn],ans[maxn],vir[maxn];
void bfs()
{
	queue<int>q;
	int v;
	q.push(1);
	while (!q.empty())
	{
	   int cur=q.front();
	   q.pop();
	   if (G[cur].size()==0)//如果当前的节点为树叶,在另一个数组中储存相应的时间(此节点是使用vector构造的节点)
	   {
	   	   ans[nu++]=tem[cur];
	   }
	   else //搜索这个节点的子节点
	   {
	      ll minn=INF;
	      for(int k=0;k<G[cur].size();k++)
	      {
	  	      v=G[cur][k];
	  	      minn=min(minn,vir[v]);//找出子节点中最小花费时间,也就是上一个节点的水全部流入某个子节点所花费的最小时间。
	  	      q.push(v);
	      }
	      for (int s=0;s<G[cur].size();s++)
	      {
	  	      v=G[cur][s];
	  	      tem[v]=tem[cur]+minn+(vir[v]-minn)*2;//按照最小时间储存父节点水完全流入每一个子节点的时间(公式:此节点时间=上一个节点的时间+此次流入最小时间+(流量-最小时间)*2),其实流量就可以看作时间,因为单位时间流1,后面称2是因为当时间最小的流完后剩下的节点按照每单位时间0.5来流。
	      }
       }  
    }
}
int main()
{
     int t,n,a,c,l,b;
     ll x;
     scanf("%d",&t);
	 tem[1]=0;
	 for (int i=0;i<t;i++)
	 {
	  scanf("%d",&n);
	  nu=0;
	  memset(ans,0,sizeof(ans));
	  memset(tem,0,sizeof(tem));
	  for (int m=0;m<=n;m++)
	  {
	  	G[m].clear();
	  }
	  for (int j=2;j<=n;j++)//这里有技巧,巧妙地构造了vector树。
	   {
	    scanf("%d%d",&a,&b);
	    vir[j]=b;
		G[a].push_back(j);
	   } 
	   bfs();
	   cin>>l;
	   sort(ans,ans+nu);//对水完全流入每一个树叶的时间做排序
	   while (l--)
	   {
	   	  scanf("%lld",&x);
	   	  ll *xx=upper_bound(ans,ans+nu,x);//upper_bound(start,end,查找数)返回要查找数的下一个数的地址;
	   	  printf("%d\n",xx-ans); 
	   }
      }
      return 0;
} 
以上有不足的欢迎指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值