码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 682C

时间:2018-07-28 17:20:42      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:top   may   fine   oid   add   题目   define   个数   col   

鸽了两天,还是我太蒟了,mayan游戏调不出来,难题又不会,只有刷水DFS才能勉强维持一下生计这样子,我还是要提高姿势水平啊!

题目描述:

给定一棵树,每条边有边权,每个点有点权,如果某个点到其子节点的距离>子节点的点权,就删去该子节点以及其所有子节点,要求删去几个点;

题解:

很明显的水DFS;

暴力DFS每个节点,记录所有点到当前节点的最大距离(这里用了贪心,到父节点最长的距离+到该子节点的距离一定是最长的距离);

在用一个数记录这个点(或其父节点)是否要删去,如果要删去,就++ans;

坑点:

1、数组一定要开大!不然会RE;

2、某个点到其子节点的距离>子节点的点权才删去,是>没有=!

附上丑陋的代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
const int MAXM=1000001;
int n,k,first[MAXM],next[MAXM],last[MAXM],point[MAXM],top,ans;
bool bo[MAXM];
struct Edge
{
    int en,len;
}edge[MAXM];
void add(int x,int y,int z)
{
    ++top;
    if(first[x]==0) first[x]=top; else next[last[x]]=top;
    last[x]=top;
    edge[top].en=y;
    edge[top].len=z;
}
void dfs(int x,__int64 y,int z)
{
    if(bo[x]) return;
    bo[x]=true;
    if(y>point[x])
        z=1;
    if(z==1)
        ++ans;
    for(int i=first[x];i;i=next[i])
    {
        dfs(edge[i].en,max(edge[i].len,y+edge[i].len),z);
    }
}
main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;++i) 
        scanf("%lld",&point[i]);
    for(int i=1;i<=n-1;++i)
    {
        int x=i+1,y,z;
        scanf("%lld%lld",&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    dfs(1,0,0);
    printf("%lld",ans);
    return 0;
}

codeforces 682C

标签:top   may   fine   oid   add   题目   define   个数   col   

原文地址:https://www.cnblogs.com/JinLeiBo/p/9382537.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!