提交: 68 解决: 14
[提交] [状态] [命题人:admin]
题目描述
You are given a tree with n nodes. The weight of the i-th node is wi . Given a positive integer m,now you need to judge that for every integer i in [1,m] whether there exists a connected subgraph which the sum of the weights of all nodes is equal to i.
输入
The first line contains an integer T (1≤T≤15) representing the number of test cases.
For each test case, the first line contains two integers n (1≤n≤3000) and m (1≤m≤100000),which are mentioned above.
The following n-1 lines each contains two integers ui and vi (1≤ui,vi≤n). It describes an edge between node ui and node vi .
The following n lines each contains an integer wi (0≤wi≤100000) represents the weight of the i-th node.
It is guaranteed that the input graph is a tree.
For each test case, the first line contains two integers n (1≤n≤3000) and m (1≤m≤100000),which are mentioned above.
The following n-1 lines each contains two integers ui and vi (1≤ui,vi≤n). It describes an edge between node ui and node vi .
The following n lines each contains an integer wi (0≤wi≤100000) represents the weight of the i-th node.
It is guaranteed that the input graph is a tree.
输出
For each test case, print a string only contains 0 and 1, and the length of the string is equal to m. If there is a connected subgraph which the sum of the weights of its nodes is equal to i, the i-th letter of string is 1 otherwise 0.
样例输入
2
4 10
1 2
2 3
3 4
3 2 7 5
6 10
1 2
1 3
2 5
3 4
3 6
1 3 5 7 9 11
样例输出
0110101010 1011111010
树的重心:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。
#include "bits/stdc++.h" using namespace std; const int maxn = 3100; int size_[maxn], sonsize[maxn], mid, val[maxn], vis[maxn]; vector<int> e[maxn]; bitset<100010> ans, s[maxn]; void dfs(int now, int fa, int n) { size_[now] = 1; sonsize[now] = 0; for (auto p:e[now]) { if (vis[p] || p == fa) continue; dfs(p, now, n); size_[now] += size_[p]; sonsize[now] = max(sonsize[now], size_[p]); } sonsize[now] = max(sonsize[now], n - sonsize[now]); if (sonsize[now] < sonsize[mid]) mid = now; } void getdp(int now, int fa) { size_[now] = 1; s[now] <<= val[now]; for (auto p:e[now]) { if (p == fa || vis[p]) continue; s[p] = s[now]; getdp(p, now); s[now] |= s[p]; size_[now] += size_[p]; } } void slove(int now) { vis[now] = 1; s[now].reset(); s[now][0] = true; getdp(now, -1); ans |= s[now]; for (auto p:e[now]) { if (!vis[p]) { mid = 0; dfs(p, -1, size_[now]); slove(mid); } } } int main() { //freopen("input.txt", "r", stdin); int _; cin >> _; sonsize[0] = 0x3f3f3f3f; while (_--) { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { e[i].clear(); vis[i] = 0; } ans.reset(); int x, y; for (int i = 1; i < n; i++) { cin >> x >> y; e[x].push_back(y); e[y].push_back(x); } for (int i = 1; i <= n; i++) { cin >> val[i]; } mid = 0; dfs(1, -1, n); slove(mid); for (int i = 1; i <= m; i++) { printf("%d", (int) ans[i]); } puts(""); } }