D题解 | #小红的树上删边#

小红的树上删边

https://ac.nowcoder.com/acm/contest/80743/D

根据题意显然可得,若从一个节点断掉一条边,以这个节点为根节点的子树大小是偶数的话,是不会影响剩余节点的奇偶性的,所以断边等于没断,那么断边其实是不需要我们真正进行操作的

既然切断一棵大小是偶数的子树不会影响剩下的奇偶性,那么我们就进行贪心即可,尽可能多的去切断一棵大小是偶数的子树,所以只要进行一次dfs,每次遇到一棵符合条件(即大小为偶数)的子树就切断它(不需要真的操作,只需要记录“切断”次数)就可以了

但其实这样会额外操作一次,具体可以自己举例子试试,所以我们要最后把操作次数-1(我的代码是直接把计数器初始化为-1)

时间复杂度O(n)

#include <bits/stdc++.h>
 
using LL = long long;
using PII = std::pair<LL, LL>;

const int MOD = 1e9 + 7;

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> size(n + 1, 1);
    std::vector<std::vector<int>> g(n + 1, std::vector<int>()); 
    for(int i = 2; i <= n; i++) {
        int a, b;
        std::cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }

    if(n%2) {
        std::cout << -1 << '\n';
        return;
    }

    int res = -1;
    std::function<void(int, int)> dfs = [&](int u, int fa) {
        for(const auto& ver : g[u]) {
            if(ver == fa) continue;
            dfs(ver, u);
            size[u] += size[ver]; //计算子树大小
        }
        
        if(size[u]%2 == 0) res++; //若子树大小为偶数就切断
    };
    std::cout << res << '\n';
}
  
int main() {
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
     
    int T = 1;
    //std::cin >> T;
    while (T--) solve();
    return 0;
}

全部评论

相关推荐

09-17 20:37
已编辑
长沙学院 Java
涂莱:学院本重心后移,金10银11,甚至金11银12,战线拉长一点,对于学院本来说秋招是个持久战,加油吧
听劝,我这个简历该怎么改...
点赞 评论 收藏
分享
昨天 00:37
已编辑
山东大学 C++
小浪_Coding:你问别人,本来就是有求于人,别人肯定没有义务免费回答你丫, 有点流量每天私信可能都十几,几十条的,大家都有工作和自己的事情, 付费也是正常的, 就像你请别人搭把手, 总得给人家买瓶水喝吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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