突然诈尸!
因为考研和读研两年没碰CF了,也是坐在XJTU工位上刷上题了,今天心血来潮想搞个每日一题,应该基本都是构造
今天让gemini帮我整理了一下构造题的常见思考方向,我们那时候哪有这条件


正文
题意
题目:
给你一颗树,让你给树的每个顶点赋权值,使的去掉树上的任意一个点后,剩下的联通块的权值相等。
思路:
Step1
识别到是树,联想到一些常见性质:度数、深度(及其奇偶性)、递归结构
Step2
手玩一些极端样例
1-2-3:叶子节点需要一样
菊花:叶子节点需要一样
Step3
考虑一般样例
这时候我们需要回头看常用的性质,用性质复现一遍完整的工作流程
这里因为有递归结构,所以考虑列方程

代码
cpp
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
if (!(cin >> n)) return;
vector<vector<int>> adj(n + 1);
vector<int> degree(n + 1, 0);
for (int i = 0; i < n - 1; ++i) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
degree[u]++;
degree[v]++;
}
vector<int> ans(n + 1);
auto dfs = [&](auto&& self, int u, int p, int sign) -> void {
ans[u] = sign * degree[u];
for (int v : adj[u]) {
if (v != p) {
self(self, v, u, -sign);
}
}
};
dfs(dfs, 1, 0, 1);
for (int i = 1; i <= n; ++i) {
cout << ans[i] << (i == n ? "" : " ");
}
cout << "\n";
}
int main() {
// ios_base::sync_with_stdio(false);
// cin.tie(NULL);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}