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

既然切断一棵大小是偶数的子树不会影响剩下的奇偶性,那么我们就进行贪心即可,尽可能多的去切断一棵大小是偶数的子树,所以只要进行一次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;
}