健康监测计划

链接:https://acm.ecnu.edu.cn/contest/317/problem/B/
思路:
按k我们来考虑k=0,那么肯定一个都不放,k=1,那么显然只能放一个,k=2呢?所有叶子结点都放,先去想k=4,那就是把叶子结点都去了,然后新的树中的叶子结点。k=3呢?就是k=4中,新选的点中随便取一个。这样一直把外圈缩进k/2次,所有的叶子结点就都是答案,那么如何判断k/2次呢,记录个深度,如果深度<=k/2并且它是叶子结点就算是要去的点。用queue把叶子结点放进来,并且每个叶子结点更新它对连的点,时间复杂度O(n)

代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6+7;
queue<int> q;
vector<int> g[maxn];
int d[maxn];
int dep[maxn];
struct Node{
    int x, d;
    bool operator < (const Node n1) const{
        return d < n1.d;
    }
};

int main()
{
    int n, k;
    cin>>n >> k;
    for(int i = 1; i <= n-1; i++){
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);g[v].push_back(u);
        d[u]++;d[v]++;
    }
    if(k == 0){
        cout << 0 << endl; return 0;
    }
    else if(k == 1) {
        cout << 1 << endl; return 0;
    }
    for(int i = 1; i <= n; i++) {
        if(d[i] == 1) {
            q.push(i);
            dep[i] = 1;
        }
    }
    int ans = 0;
    while(!q.empty()){
        int tmp = q.front(); q.pop();
        ans++;
        for(auto to : g[tmp]){
            dep[to] = max(dep[to], dep[tmp]+1); 
            if(dep[to] <= k/2 && --d[to] == 1){
                q.push(to);
            }
        }
    }
    cout << min(n, ans+k%2);

}
全部评论

相关推荐

🎓学历背景:双非土木硕👨‍💻意向职位:AI应用开发大佬们可以帮我看看简历吗,秋招至今0offer
秋招结束再玩瓦:今年科班都不好找哇……你可以试试交叉岗,比如制造业国企的一些开发算法,或者互联网的边缘岗,it技术支持,运维这些
我的简历长这样
点赞 评论 收藏
分享
给🐭🐭个面试机会...:我擦seed✌🏻
点赞 评论 收藏
分享
09-22 15:45
门头沟学院 Java
谁给娃offer我给...:我也遇到了,我说只要我通过面试我就去,实际上我根本就不会去😁
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务