[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

= 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("");
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章