2017 CCPC 哈尔滨站 题解

题目链接  2017 CCPC Harbin

Problem A

Problem B

Problem D

Problem F

Problem L

考虑二分答案。

设当前待验证的答案为x

我们可以把第二个条件转化为在子树中最多有几个点是黑色的。

那么我们可以根据这些条件求出以每个点为根的子树的黑点数范围,做一次dfs。

最后看看根结点的范围是否包含x即可。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define MP		make_pair
#define fi		first
#define se		second


typedef long long LL;
typedef pair <int, int> PII;

const int N = 1e5 + 10;

int sz[N];
int T, n;
int lima, limb;
int l, r;
int flag;
int c[N], d[N], cc[N], dd[N];
vector <int> v[N];
PII la[N], lb[N];

void dfs(int x, int fa){
	sz[x] = 1;
	for (auto u : v[x]){
		if (u == fa) continue;
		dfs(u, x);
		sz[x] += sz[u];
	}
}

void calc(int x, int fa){
	int xx = 0, yy = 1;
	for (auto u : v[x]){
		if (u == fa) continue;
		calc(u, x);
		xx += c[u], yy += d[u];
	}

	c[x] = max(c[x], xx);
	d[x] = min(d[x], yy);
}

bool check(int x){
	rep(i, 1, n) c[i] = cc[i], d[i] = dd[i];
	rep(i, 1, lima) c[la[i].fi] = max(c[la[i].fi], la[i].se);
      	rep(i, 1, limb) d[lb[i].fi] = min(d[lb[i].fi], x - lb[i].se);
	calc(1, 0);
	rep(i, 1, n) if (c[i] > d[i]) return false;
	if (x >= c[1] && x <= d[1]) return true; else return false;
}

int main(){

	scanf("%d", &T);
	while (T--){
		scanf("%d", &n);
		rep(i, 0, n + 1) v[i].clear();
		rep(i, 2, n){
			int x, y;
			scanf("%d%d", &x, &y);
			v[x].push_back(y);
			v[y].push_back(x);
		}

		rep(i, 0, n + 1) sz[i] = 0;
		dfs(1, 0);

		rep(i, 1, n) cc[i] = 0, dd[i] = sz[i];
		flag = 1;

		scanf("%d", &lima);
		rep(i, 1, lima){
			scanf("%d%d", &la[i].fi, &la[i].se);
			if (sz[la[i].fi] < la[i].se){
				flag = 0;
			}
		}

		scanf("%d", &limb);
		rep(i, 1, limb){
			scanf("%d%d", &lb[i].fi, &lb[i].se);
			if (n - sz[lb[i].fi] < lb[i].se){
				flag = 0;
			}
		}

		if ((!flag) || (!check(n))){
			puts("-1");
			continue;
		}

		l = 0, r = n;
		while (l + 1 < r){
			int mid = (l + r) >> 1;
			if (check(mid)) r = mid;
			else l = mid + 1;
		}
		
		if (check(l)) printf("%d\n", l);
		else printf("%d\n", r);	
	}

	return 0;
}

  

 

Problem M

 

posted @ 2017-11-28 21:37  cxhscst2  阅读(884)  评论(0编辑  收藏  举报