1. 程式人生 > 其它 >CodeTON Round 1 E. Equal Tree Sums

CodeTON Round 1 E. Equal Tree Sums

傳送門

題目大意

一棵 \(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\)

的正負性,於是刪去 \(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;
}