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.

Input:

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.

Output :

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.
Example
standard input

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

standard output

0110101010

1011111010

题意:给你一棵树 询问现在小于等于m的权值出现情况 权值是任意联通子树的点权和

思路:对于第i个节点 我们把问题的规模分成 包含i点的子树 不包含i点的子树 对于第二种情况 可以递归求解

在计算经过i点的图的权值的时候我们可以用bitset来标记 很巧妙 具体操作可以看代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define ll long long int
using namespace std;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
int head[3007],vis[3007];
int d[3007],val[3007];
struct node{
int to,next;
};
node edge[6007];
int cnt,n,m;
void init(){
cnt=0;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
}
void add(int from,int to){
edge[++cnt].to=to;
edge[cnt].next=head[from];
head[from]=cnt;
}
int son[3007];
int now_size,sz,root;
void find_root(int u,int fa){
son[u]=1; int res=-inf;
for(int i=head[u];i;i=edge[i].next){
if(vis[edge[i].to]||edge[i].to==fa) continue;
int to=edge[i].to;
find_root(to,u);
son[u]+=son[to];
res=max(res,son[to]);
}
res=max(res,sz-son[u]);
if(res<now_size) now_size=res,root=u;
}
bitset<100007>bits[3007],ans;
void solve(int u,int fa){
bits[u]<<=val[u]; //把之前出现过的权值都加上val[u]
for(int i=head[u];i;i=edge[i].next){
if(vis[edge[i].to]||edge[i].to==fa) continue;
int to=edge[i].to;
bits[to]=bits[u]; //向下传递
solve(to,u);
bits[u]|=bits[to]; //收集信息
}
}
void dfs(int u){ //分治
vis[u]=1;
bits[u].reset();
bits[u].set(0); //把0位置的置1
solve(u,0);
ans|=bits[u];
int totsz=sz;
for(int i=head[u];i;i=edge[i].next){
if(vis[edge[i].to]) continue;
int to=edge[i].to;
now_size=inf; root=0;
sz=son[to]>son[u]?totsz-son[u]:son[to];
find_root(to,0);
dfs(root);
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
init();
ans.reset();
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
int from,to;
scanf("%d%d",&from,&to);
add(from,to); add(to,from);
}
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
now_size=inf,sz=n,root=0;
find_root(1,0);
dfs(root);
for(int i=1;i<=m;i++)
printf("%d",(int)ans[i]);
printf("\n");
}
return 0;
}

hdu 6268 Master of Subgraph(点分治+bitset)的更多相关文章

  1. HDU - 6268: Master of Subgraph (分治+bitset优化背包)

    题意:T组样例,给次给出一个N节点的点权树,以及M,问连通块的点权和sum的情况,输出sum=1到M,用0或者1表示. 思路:背包,N^2,由于是无向的连通块,所以可以用分治优化到NlgN. 然后背包 ...

  2. HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)

    题目链接  2017 CCPC Hangzhou  Problem E 题意  给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...

  3. 算法学习分析-点分治 HDU 6269 Master of Subgraph

    首先给出定义 点分治是一种处理树上路径的工具 挂出一道题目来:Master of Subgraph 这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生 这道题目,假如我们利 ...

  4. Master of Subgraph

    Problem E. Master of SubgraphYou are given a tree with n nodes. The weight of the i-th node is wi. G ...

  5. [HDU6268]Master of Subgraph

    [HDU6268]Master of Subgraph 题目大意: 一棵\(n(n\le3000)\)个结点的树,每个结点的权值为\(w_i\).给定\(m(m\le10^5)\),对于任意\(i\i ...

  6. CCPC 2016 杭州 E. Master of Subgraph(点分治+bitset优化DP)

    题目链接:http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 题意:给定一棵有 n 个结点的树和一个数 m,对于 i ∈ ...

  7. Hdu 6268 点分治 树上背包 bitset 优化

    给你一颗大小为n(3000)的树,树上每个点有点权(100000),再给你一个数m(100000) i为1~m,问树中是否存在一个子图,使得权值为i. 每次solve到一个节点 用一个bitset维护 ...

  8. HDU 5016 Mart Master II (树上点分治)

    题目地址:pid=5016">HDU 5016 先两遍DFS预处理出每一个点距近期的基站的距离与基站的编号. 然后找重心.求出每一个点距重心的距离.然后依据dis[x]+dis[y] ...

  9. HDU 5324 Boring Class【cdq分治】

    这就是一个三维排序的问题,一维递减,两维递增,这样的问题用裸的CDQ分治恰好能够解决. 如同HDU 4742(三维排序,一个三维都是递增的) 由于最小字典序比較麻烦,所以要从后面往前面做分治.每一个点 ...

随机推荐

  1. PHP 获取重复数组中 第二多的元素

    $target = ["重复项目", "repeat", "repeat", "重复", "重复项目" ...

  2. 【Linux】awk想打印制定列以后的所有列

    今天偶然研究awk,有一个文件,文件内容是全篇的1 2 3 4 5 6 7 8 9 0 现在想打印除了第一列意外的所有列 文件内容: [root@localhost ~]# cat test.txt ...

  3. kubernets之服务的实现方式

    一  服务如何通过kubernetes集群的组件来实现其功能 1.1  节点上的所有的服务相关的功能实现都是通过节点上面的kube-proxy来实现的,服务提供了一个或者多个服务IP以及端口对客户端开 ...

  4. kubernets之pod的标签拓展

    一 标签的拓展使用 1.1 标签的作用范围不仅仅适用于pod对node以及其他类的大部分资源同样适用 k label node node01 gpu=true k是kubectl的别名形式 同样对于n ...

  5. 两行代码修复了解析MySQL8.x binlog错位的问题!!

    写在前面 MySQL是互联网行业使用的最多的关系型数据库之一,而且MySQL又是开源的,对于MySQL的深入研究,能够加深我们对于数据库原理的理解.自从开源了mykit-data之后,不少小伙伴试用后 ...

  6. CTFHub - Web(六)

    命令注入: 1.进入页面,测试127.0.0.1, 关键代码: <?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip'] ...

  7. SAP中的事务锁

    我们知道sap中的事物锁tcode是SM01. 细细研究发现,其实无外乎就是将tstc表中的事务码对应的字段CINFO的值加上HEX20 解锁就是还原成原来的值. 当然也发现了,调用了一个系统函数AU ...

  8. 机器学习7-模型保存&无监督学习

    模型保存和加载 sklearn模型的保存和加载API from sklearn.externals import joblib 保存:joblib.dump(rf, 'test.pkl') 加载:es ...

  9. .NET Core部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx 或 Jexus)

    在前两篇: .NET Core部署到linux(CentOS)最全解决方案,常规篇 .NET Core部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx) 我们对. ...

  10. STL_常用的算法

    STL_常用的算法 一.常用的查找算法 adjacent_find() adjacent_find(iterator beg, iterator end, _callback); 在iterator对 ...