夹克老爷的愤怒

夹克老爷逢三抽一之后,由于采用了新师爷的策略,乡民们叫苦不堪,开始组织起来暴力抗租。
夹克老爷很愤怒,他决定派家丁常驻村中进行镇压。
诺德县 有N个村庄,编号0 至 N-1,这些村庄之间用N - 1条道路连接起来。
家丁都是经过系统训练的暴力机器,每名家丁可以被派驻在一个村庄,并镇压当前村庄以及距离该村庄不超过K段道路的村庄。
夹克老爷一贯奉行最小成本最大利润的原则,请问要实现对全部村庄的武力控制,夹克老爷需要派出最少多少名家丁?

Input
第1行:2个数N, K中间用空格分隔(1<= N <= 100000, 0 <= K <= N)。
之后N-1行:每行2个数S, E中间用空格分隔,表示编号为S的村庄同编号为E的村庄之间有道路相连。(0 <= S, E < N)。
Output
输出一个数说明要实现对全部村庄的武力控制,夹克老爷需要派出最少多少名家丁?
Input示例
4 1
0 1
0 2
0 3
Output示例

1

#include <iostream>    
#include <algorithm>    
#include <cmath>    
#include <vector>    
#include <string>    
#include <cstring>    
#pragma warning(disable:4996)    
using namespace std;  
  
#define inf 0x3f3f3f3f  
const int MAXN = 1e5 + 50;
int res;  
int n, k;  
int s, e;   
int used[MAXN];  
int dp[MAXN];  
vector<int>node[MAXN];  
  
void dfs(int x)  
{  
    used[x] = 1;  
    int minn = inf;  
    int maxn = -inf;  
    int size = node[x].size();  
  
    int i;  
    for (i = 0; i < size; i++)  
    {  
        int temp = node[x][i];  
        if (used[temp] == 0)  
        {  
            dfs(temp);  
            minn = min(minn, dp[temp]);  
            maxn = max(maxn, dp[temp]);  
        }  
    }  
    if (minn == inf)  
    {  
        dp[x] = -1;  
    }  
    else if (minn <= -k)  
    {  
        res++;  
        dp[x] = k;  
    }  
    else if (maxn + minn > 0)  
    {  
        dp[x] = maxn - 1;  
    }  
    else  
    {  
        dp[x] = minn - 1;  
    }  
    used[x] = 0;  
}  
  
int main()  
{  
    int i;  
    cin >> n >> k;
    for (i = 1; i <= n - 1; i++)  
    {  
        cin >> s >> e;
        s++;  
        e++;  
        node[s].push_back(e);  
        node[e].push_back(s);  
    }  
    if (k == 0)  
    {  
        cout << n << endl;
        return 0;  
    }  
    dfs(1);  
  
    if (dp[1] < 0)  
    {  
        res++;  
    }  
    cout << res << endl;
    
    return 0;  
}  

阅读更多
个人分类: 树形DP
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭