[HDU6268]Master of Subgraph 树分治+bitset

bitset用法

bitset<B_Length> array[A_SIZE]  创建一个长度为B_Length,大小为A_SIZE的数组

bitset<B> a(n)                                初始化一个值为n的bitset

.reset()                                            将所有位初始化为0

.set()                                               将所有位初始化为1

.any()                                              是否有某一位为1

= x && x belong to int                    将x的值赋给bitset转化为2进制表示

bitset支持左移右移各种位运算操作

 

树分治

对于每个点,如果要取某点的子节点,那么必然会经过该节点, 故合并的时候有 b[v]<<val[v]操作

 

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 3e3 + 5;
const int MAX_M = 1e5 + 5;
vector<int> G[MAX_N];
int s[MAX_N], d[MAX_N], f[MAX_N], root, sz, n, m, val[MAX_N];
bool used[MAX_N];
bitset<MAX_M> b[MAX_N], ans;

void get_r(int u, int p) {
	f[u] = 0; s[u] = 1;
	for (auto v : G[u]) {
		if (used[v] || v == p) continue;
		get_r(v, u);
		f[u] = max(f[u], s[v]);
		s[u] += s[v];
	}
	f[u] = max(f[u], sz - f[u]);
	if (f[u] < f[root]) root = u;
}

void get_v(int u, int p) {
	b[u] <<= val[u];
	s[u] = 1;
	for (auto v : G[u]) {
		if (!used[v] && v != p) {
			b[v] = b[u];
			get_v(v, u);
			b[u] |= b[v];
			s[u] += s[v];
		}
	}
}

void solve(int u) {
	used[u] = true;
	b[u] = 1;
	get_v(u, 0);
	ans |= b[u];

	for (auto v : G[u]) {
		if (!used[v]) {
			sz = s[v]; root = 0;
			get_r(v, u);
			solve(root);
		}
	}
}


int main() {
	int T; cin >> T; while(T--) {
		//clear
		cin >> n >> m;
		memset(used, false, sizeof used);
		for (int i = 1; i <= n; i++) G[i].clear();
		ans.reset();
		for (int i = 0; i < n - 1; i++) {
			int a, b; scanf("%d%d", &a, &b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		for (int i = 1; i <= n; i++) {
			scanf("%d", &val[i]);
		}
		f[0] = n + 5;
		sz = n;
		get_r(1, root);
		solve(root);
		for (int i = 1; i <= m; i++) {
			printf("%d", (int)ans[i]);
		}
		puts("");
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值