hdu 6268 Master of Subgraph(点分治+bitset)
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)的更多相关文章
- HDU - 6268: Master of Subgraph (分治+bitset优化背包)
题意:T组样例,给次给出一个N节点的点权树,以及M,问连通块的点权和sum的情况,输出sum=1到M,用0或者1表示. 思路:背包,N^2,由于是无向的连通块,所以可以用分治优化到NlgN. 然后背包 ...
- HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)
题目链接 2017 CCPC Hangzhou Problem E 题意 给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...
- 算法学习分析-点分治 HDU 6269 Master of Subgraph
首先给出定义 点分治是一种处理树上路径的工具 挂出一道题目来:Master of Subgraph 这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生 这道题目,假如我们利 ...
- 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 ...
- [HDU6268]Master of Subgraph
[HDU6268]Master of Subgraph 题目大意: 一棵\(n(n\le3000)\)个结点的树,每个结点的权值为\(w_i\).给定\(m(m\le10^5)\),对于任意\(i\i ...
- CCPC 2016 杭州 E. Master of Subgraph(点分治+bitset优化DP)
题目链接:http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 题意:给定一棵有 n 个结点的树和一个数 m,对于 i ∈ ...
- Hdu 6268 点分治 树上背包 bitset 优化
给你一颗大小为n(3000)的树,树上每个点有点权(100000),再给你一个数m(100000) i为1~m,问树中是否存在一个子图,使得权值为i. 每次solve到一个节点 用一个bitset维护 ...
- HDU 5016 Mart Master II (树上点分治)
题目地址:pid=5016">HDU 5016 先两遍DFS预处理出每一个点距近期的基站的距离与基站的编号. 然后找重心.求出每一个点距重心的距离.然后依据dis[x]+dis[y] ...
- HDU 5324 Boring Class【cdq分治】
这就是一个三维排序的问题,一维递减,两维递增,这样的问题用裸的CDQ分治恰好能够解决. 如同HDU 4742(三维排序,一个三维都是递增的) 由于最小字典序比較麻烦,所以要从后面往前面做分治.每一个点 ...
随机推荐
- tp where使用数组条件,如何设置or,and
1 //where条件数组拼接 2 $where['status'] = 1; 3 $maps['id'] = ['in', implode(',', $r_ids)]; 4 $maps['uid'] ...
- 无限重置IDE过期时间插件 亲测可以使用
相信破解过IDEA的小伙伴,都知道jetbrains-agent这个工具,没错,就是那个直接拖入到开发工具界面,一键搞定,so easy的破解工具!这个工具目前已经停止更新了,尽管还有很多小伙伴在使用 ...
- 【Oracle】查看oracle表空间大小及增加表空间的几种方法
在oracle中表空间是必不可少的.但是怎么查看表空间呢 简单的查看方式是: SQL> select tablespace_name from dba_tablespaces; 想要查看表空间对 ...
- kubernets之节点和网络的安全保障策略
一 在pod中使用宿主节点的命名空间 1.1 在pod中使用宿主的网络命名空间 [root@node01 Chapter13]# cat pod-with-host-network.yml api ...
- 修改conda和pip源
修改conda源为中科大源 Windows修改C:\Users\user(user替换为当前登陆系统的用户)目录下的.condarc文件 Linux修改家目录下的.condarc文件 channels ...
- 图像分割论文 | DRN膨胀残差网络 | CVPR2017
文章转自:同作者个人微信公众号[机器学习炼丹术].欢迎交流沟通,共同进步,作者微信:cyx645016617 论文名称:'Dilated Residual Networks' 论文链接:https:/ ...
- CS_WHERE_USED_MAT 反查BOM的成品CS15
可能很多人都用过BOM展开的函数,但是有的时候,需要通过组件去反查BOM的成品,而这时候就需要用到函数 CS_WHERE_USED_MAT来实现,而对于CS_WHERE_USED_MAT只能反查到上一 ...
- celery应用
celery---分布式任务队列 Celery是一个简单,灵活且可靠的分布式系统,可以处理大量消息,同时为操作提供维护该系统所需的工具. Celery是一个基于python开发的模块,可以帮助我们对任 ...
- k8s之PV、PVC、StorageClass详解
导读 上一篇写了共享存储的概述以及一个简单的案例演示.这一篇就写一下PV和PVC. PV是对底层网络共享存储的抽象,将共享存储定义为一种"资源",比如Node也是容器应用可以消费的 ...
- 京东零售mockRpc实践
https://mp.weixin.qq.com/s/A0T6ySub0DfQiXJAbWm2Qg jsf协议是基于tcp的而且对数据进行了序列化.加密等操作,直接截获的方式很难实现.最后决定注入自己 ...