vijos 国土继承 思维+dfs

题意:

一个国王有两个儿子,两个儿子已经长大了,国王想拿N座城市分给这两个儿子,使其二人锻炼统帅王国的能力。

为了公平起见,要给这两个儿子的尽量平均的资源。

问你每个大儿子和小儿子分别能获得的资源数量。

注:这N座城市是联通的,分给每个人的城市也是联通的。且任意两个城市间有且仅有一条路。

不能平分则照顾小儿子


思路:

这题还很水的,不过是我当时傻逼了

题目要求分出的两块是分别联通的,通过观察发现,树里的每一条边刚好可以把一棵树分成两部分。

那么我们这题的思路就是枚举一条边分成两部分然后看哪个满足题意就可以了。

我们随便找一个点当根跑一遍dfs,然后记录sum, 表示每个点往下子树的和,同时记录深度,枚举边的时候判断一下就好了. = =傻逼


#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long ll;
const ll mod=1e9+7;
const int maxn=5e5+10;
int n;
int l[maxn],r[maxn];
ll sum[maxn],a[maxn],depth[maxn];
const ll inf = 1e18;
vectorvt[maxn];
void dfs(int x,int fa,int d)
{
	sum[x] = a[x];
	depth[x] = d;
	for(int i = 0;i < vt[x].size();++i)
	{
		int v = vt[x][i];
		if(v == fa) continue;
		dfs(v,x,d+1);
		sum[x] += sum[v];
	}
	return ;
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i = 0;i < n;i++)
		vt[i].clear(),sum[i] = 0,depth[i] = 0;
		for(int i = 1;i <= n;i++)
		scanf("%lld",&a[i]);
		for(int i = 1; i < n;i++)
		{
			int u,v;
			scanf("%d %d",&u,&v);
			vt[u].push_back(v);
			vt[v].push_back(u);
			l[i] = u,r[i] = v;
		}
		dfs(1,-1,1);
		//cout<



你可能感兴趣的:(搜索,思维)