51Nod-1378-夹克老爷的愤怒

来源:互联网 发布:百度 mac 五笔 词库 编辑:程序博客网 时间:2024/06/09 16:15

ACM模版

描述

描述

题解

这个题和这一段时间的那个拉钩测评选择的最后一道题极其相似,那个题好像叫做监狱逃离,是一个七级算法,但是和这个题几乎是一样的,同样都是树,也都是树归,找一个结点作为根后开始深入,一直深入到最深层也就是说叶子结点后,开始回朔的过程中,不断进行状态的迁移,这里需要注意的是,两个题都是要考虑到同级子树的相互影响关系,这里的同级子树指得是根的父亲是同一个结点的多棵子树……这里我写的代码思路和标程略微差别,表示的是这个子树中离根最远的距离有多远,当根的距离大于等于 K 时,我们就在这个部位放置一个家丁,此时,将这个结点的状态置为 -K,因为我们知道每个家丁都可以控制 K 的范围,所以他还能向上控制 K 个,这里我们用负数表示,和标程恰好相反……具体代码不难理解,子树之间的作用关系和标程是相似的,没毛病~~~

代码

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>using namespace std;const int MAXN = 1e5 + 5;const int INF = 0x3f3f3f3f;int N, K;int ans;int cnt = 0;int dg[MAXN];           //  度int dp[MAXN];vector<int> vi[MAXN];void dfs(int x, int pre){    int max_ = -INF;    int min_ = INF;    for (int i = 0; i < vi[x].size(); i++)    {        if (vi[x][i] != pre)        {            dfs(vi[x][i], x);            max_ = max(max_, dp[vi[x][i]]);            min_ = min(min_, dp[vi[x][i]]);        }    }    if (max_ == -INF)    {        max_ = min_ = 0;    }    if (max_ >= K)    {        ans++;        dp[x] = -K;    }    else if (min_ < 0 && min_ + max_ < 0)    {        dp[x] = min_ + 1;    }    else    {        dp[x] = max_ + 1;    }}int main(){//    freopen("/Users/zyj/Desktop/input.txt", "r", stdin);    cin >> N >> K;    int x, y;    for (int i = 1; i < N; i++)    {        scanf("%d%d", &x, &y);        vi[x].push_back(y);        vi[y].push_back(x);        dg[x]++;        dg[y]++;    }    dfs(0, -1);    if (dp[0] > 0)    {        ans++;    }    printf("%d\n", ans);    return 0;}
原创粉丝点击