• Codeforces Round #358 (Div. 2)——C. Alyona and the Tree(树的DFS+逆向思维)


    C. Alyona and the Tree
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Alyona decided to go on a diet and went to the forest to get some apples. There she unexpectedly found a magic rooted tree with root in the vertex 1, every vertex and every edge of which has a number written on.

    The girl noticed that some of the tree's vertices are sad, so she decided to play with them. Let's call vertex v sad if there is a vertex u in subtree of vertex v such that dist(v, u) > au, where au is the number written on vertex udist(v, u) is the sum of the numbers written on the edges on the path from v to u.

    Leaves of a tree are vertices connected to a single vertex by a single edge, but the root of a tree is a leaf if and only if the tree consists of a single vertex — root.

    Thus Alyona decided to remove some of tree leaves until there will be no any sad vertex left in the tree. What is the minimum number of leaves Alyona needs to remove?

    Input

    In the first line of the input integer n (1 ≤ n ≤ 105) is given — the number of vertices in the tree.

    In the second line the sequence of n integers a1, a2, ..., an (1 ≤ ai ≤ 109) is given, where ai is the number written on vertex i.

    The next n - 1 lines describe tree edges: ith of them consists of two integers pi and ci (1 ≤ pi ≤ n - 109 ≤ ci ≤ 109), meaning that there is an edge connecting vertices i + 1 and pi with number ci written on it.

    Output

    Print the only integer — the minimum number of leaves Alyona needs to remove such that there will be no any sad vertex left in the tree.

    Example
    input
    9
    88 22 83 14 95 91 98 53 11
    3 24
    7 -8
    1 67
    1 64
    9 65
    5 12
    6 -80
    3 8
    
    output
    5
    
    Note

    The following image represents possible process of removing leaves from the tree:


    比较有意思的一道题,刚开始题意理解错了,以为一定是从1开始,后来发现是最远可以是1,最近就是从父节点开始,那么边权和就变成了Max{0(舍弃之前的边从最近的父节点开始),sumpre(加上之前的边)}。然后再发现这道题也叫什么树形DP,反正也就听过的样子。一开始写BFS只能过两组数据,因为无法知道到底最合适起点在哪里。因此要用动态的思想,一开是BFS去计算减掉多少枝叶,看了别人博客才明白用逆向思维,因为你减掉的枝叶可能会重复,也可能这个枝叶根本不是从最优开始点开始计算的,也就无法得知这个节点到底算不算sad……题意是若中间出现了一个sad,那么这个sad点的后代点全部都要摘掉,因此去计算从1开始向外拓展的可保留点比较好,那显然就是DFS了。还有由于是无向图,边数要乘以2,两次RE

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define MM(x) memset(x,0,sizeof(x))
    #define MMINF(x) memset(x,INF,sizeof(x))
    typedef long long LL;
    const double PI=acos(-1.0);
    const int N=200010;
    int r;
    struct info
    {
    	int to;
    	int pre;
    	int d;
    }E[N];
    int head[N],cnt,w[N],vis[N];
    void add(int s,int t,int dx)
    {
    	E[cnt].to=t;
    	E[cnt].pre=head[s];
    	E[cnt].d=dx;
    	head[s]=cnt++;
    }
    void init()
    {
    	memset(head,-1,sizeof(head));
    	MM(w);MM(vis);
    	cnt=0;
    	r=0;
    }
    void dfs(const int &now,const int &pre,const LL &nowval)
    {
    	if(w[now]<nowval||vis[now])
    		return ;
    	vis[now]=1;
    	r++;
    	for (int i=head[now]; i!=-1; i=E[i].pre)
    	{
    		int v=E[i].to;
    		dfs(v,now,max<LL>((LL)0,((LL)nowval+(LL)E[i].d)));
    	}
    }
    int main(void)
    {
    	int n,i,j,x,y;
    	while (~scanf("%d",&n))
    	{
    		init();
    		for (i=1; i<=n; i++)
    		{
    			scanf("%d",&w[i]);
    		}
    		for (i=1; i<=n-1; i++)
    		{
    			scanf("%d%d",&x,&y);
    			add(i+1,x,y);
    			add(x,i+1,y);
    		}
    		dfs(1,1,(LL)0);
    		printf("%d
    ",n-r);
    	}
    	return 0;
    }
  • 相关阅读:
    Redis 设计与实现 2:Redis 对象 redisObject
    Redis 设计与实现 1:数据库 redisDb
    KafkaProducer 简析
    G1 收集器
    KafkaMirrorMaker 的不足以及一些改进
    Redis 数据结构与对象编码 (Object Encoding)
    跨境 TCP 传输优化实录 — 使用 BBR 解决 LFN 问题
    TCP 协议简析
    使用模拟退火算法优化 Hash 函数
    LSM-Tree 与 B-Tree
  • 原文地址:https://www.cnblogs.com/Blackops/p/5766323.html
Copyright © 2020-2023  润新知