Codeforces Global Round 16 E Buds Re-hanging
阿新 • • 發佈:2021-09-13
https://codeforces.com/contest/1566/problem/E
const int maxn = 2e5 + 10; vector<int> g[maxn]; int f1 = 0, f2 = 0, ans = 0; int sz[maxn]; //dfs判斷每個點是bud還是lef還是other //如果發現了一個bud,那麼我們先把bud放到root下 //當拿掉了bud以後,它的父節點可能變成lef或者bud或者other //如果父節點變成lef,就按lef返回,變成bud就按bud返回 //最後得到bud的數量f,如果除root外所有節點都在bud上,ans -= f - 1,否則就是ans -= f //就是說每個bud都可以減少一個lef,但是如果一開始沒有lef,第一個bud就不能減少lef int dfs(int now, int fa) { sz[now] = 0; if(g[now].size() == 1) {//lef ans ++; return 1; } int son = 0, bud = 0; for(auto it : g[now]) { if(it == fa) continue; int res = dfs(it, now); if(res == 1) son ++; else if(res == 2) bud ++; } if(son == g[now].size() - 1) {//bud sz[now] = son + 1; f1 ++; return 2; } else { if(bud == g[now].size() - 1) {//lef if(now != 1) ans ++; return 1; } else if(son + bud == g[now].size() - 1) {//bud sz[now] = son + 1; f1 ++; return 2; } else return 0; } } void run() { int n; cin >> n; f1 = f2 = ans = 0; for(int i = 1; i <= n; ++ i) g[i].clear(); g[1].push_back(1); for(int i = 1; i < n; ++ i) { int u, v; cin >> u >> v; g[v].push_back(u); g[u].push_back(v); } dfs(1, 1); if(sz[1]) f1 --; int sum = 0; //for(int i = 1; i <= n; ++ i) cout << sz[i] << ' '; cout << '\n'; for(int i = 2; i <= n; ++ i) sum += sz[i]; if(sum == n - 1) ans -= f1 - 1; else ans -= f1; cout << ans << '\n'; return ; }