cf 682C

来源:互联网 发布:中国js 12.7mm狙击步枪 编辑:程序博客网 时间:2024/06/05 11:03

原题:点击打开链接

给你一棵树,1为该树的根只要有任意一条到i的路径是大于num[i],就要将该点和该点子树删掉。

从1开始搜索路径,取一到任意点的最大路径,若最大路径大于num[i],则可以将该点与子树删除。当路径为负数时要清零。


#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <vector>using namespace std;const int maxn=1e5+5;vector<int> s[maxn],w[maxn],c[maxn];int n,sum,num[maxn],vis[maxn],viss[maxn],k,flag;long long w1[maxn],wmax[maxn];void dfs2(int u){    for(int i=0;i<s[u].size();i++)    {        if(!vis[s[u][i]])            vis[s[u][i]]=1;        dfs2(s[u][i]);    }}void dfs1(int u){    for(int i=0;i<s[u].size();i++)    {        int v=s[u][i];        if(vis[v])            continue;        w1[v]=w1[u]+w[u][i];        wmax[v]=max(wmax[v],w1[v]);        if(w1[v]<0)            w1[v]=0;        if(wmax[v]>num[v]){            vis[v]=1;            dfs2(v);        }        if(!vis[v])        dfs1(v);    }}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=1;i<=n;i++)        {            int a;            scanf("%d",&a);            num[i]=a;        }        for(int i=1;i<=n-1;i++)        {            int a,b;            scanf("%d%d",&a,&b);            s[a].push_back(i+1);            w[a].push_back(b);     //       c[a].push_back(i+1);        }        sum=0;        memset(vis,0,sizeof(vis));        memset(w1,0,sizeof(w1));        memset(wmax,0,sizeof(wmax));        dfs1(1);        for(int i=2;i<=n;i++)            if(vis[i])                sum++;        printf("%d\n",sum);    }}


0 0
原创粉丝点击