結果

問題 No.3348 Tree Balance
コンテスト
ユーザー kotatsugame
提出日時 2025-11-13 22:11:20
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 686 ms / 5,000 ms
コード長 1,434 bytes
コンパイル時間 981 ms
コンパイル使用メモリ 82,428 KB
実行使用メモリ 70,396 KB
最終ジャッジ日時 2025-11-13 22:11:56
合計ジャッジ時間 8,257 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 25
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
#include<cassert>
using namespace std;
int N;
int W[2<<17];
vector<int>G[2<<17];
vector<long>S;
int L[2<<17],R[2<<17];
long dfs0(int u,int p)
{
	L[u]=S.size();
	S.push_back(W[u]);
	long sum=W[u];
	for(int v:G[u])if(v!=p)sum+=dfs0(v,u);
	S[L[u]]=sum;
	R[u]=S.size();
	return sum;
}
long ALL,ans=9e18;
set<long>Lft,ret;
long f(long x,long y,long z){return max({x,y,z})-min({x,y,z});}
void dfs1(int u,int p)
{
	if(p!=-1)
	{
		{//lft
			long dn=S[L[u]];
			long rest=ALL-dn;
			long mid=rest/2;
			auto it=Lft.lower_bound(mid);
			if(it!=Lft.end())ans=min(ans,f(dn,rest-*it,*it));
			if(it!=Lft.begin())
			{
				it--;
				ans=min(ans,f(dn,rest-*it,*it));
			}
		}
	}
	set<long>cur;
	for(int v:G[u])if(v!=p)
	{
		dfs1(v,u);
		if(cur.size()<ret.size())swap(cur,ret);
		for(long v:ret)cur.insert(v);
	}
	if(p!=-1)
	{
		{//lower
			long up=ALL-S[L[u]];
			long mid=S[L[u]]/2;
			auto it=cur.lower_bound(mid);
			if(it!=cur.end())ans=min(ans,f(up,S[L[u]]-*it,*it));
			if(it!=cur.begin())
			{
				it--;
				ans=min(ans,f(up,S[L[u]]-*it,*it));
			}
		}
	}
	cur.insert(S[L[u]]);
	swap(ret,cur);
	Lft.insert(S[L[u]]);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin>>N;
	for(int i=0;i<N;i++)cin>>W[i];
	for(int i=1;i<N;i++)
	{
		int u,v;cin>>u>>v;
		u--,v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	ALL=dfs0(0,-1);
	dfs1(0,-1);
	cout<<ans<<endl;
}
0