CodeTON Round 1 E. Equal Tree Sums
阿新 • • 發佈:2022-03-25
題目大意
一棵 \(n(3\leq n\leq 10^5)\) 個節點的無根樹,為每個節點 \(i\) 賦予一個權值 \(a_i(-10^5\leq a_i\leq 10^5,a_i\neq 0)\) ,使得在刪去任意一個節點後,剩下的各個連通塊的權值和都相等。
思路
我們對這棵樹做二分圖染色,一部分的節點賦予 \(deg_v\) 的權值,另一部分的節點賦予 \(-deg_v\) 的權值,這樣在刪去某個頂點 \(u\) 後,連通塊中所有不與 \(u\) 相連的邊會為該連通塊權值的總和貢獻一個 \(1\) 和一個 \(-1\) ,總的貢獻為 \(0\) ,而該連通塊與 \(u\) 的連邊對總和的貢獻取決於 \(w_u\)
程式碼
#include<bits/stdc++.h> #include<unordered_map> #include<unordered_set> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PII; #define all(x) x.begin(),x.end() //#define int LL //#define lc p*2+1 //#define rc p*2+2 #define endl '\n' #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #pragma warning(disable : 4996) #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) const double eps = 1e-8; const LL MOD = 100000000; const LL mod = 998244353; const int maxn = 200010; vector<int>G[maxn]; int T, N; int ans[maxn]; void add_edge(int from, int to) { G[from].push_back(to); G[to].push_back(from); } void dfs(int v, int p, int t) { if (!t) ans[v] = -ans[v]; for (auto to : G[v]) { if (to == p) continue; dfs(to, v, t ^ 1); } } void solve() { dfs(1, 0, 0); for (int i = 1; i <= N; i++) cout << ans[i] << ' '; cout << endl; } int main() { IOS; cin >> T; while (T--) { cin >> N; for (int i = 1; i <= N; i++) G[i].clear(), ans[i] = 0; int u, v; for (int i = 1; i < N; i++) { cin >> u >> v; add_edge(u, v); ans[u]++, ans[v]++; } solve(); } return 0; }