[HDU6268]Master of Subgraph
[HDU6268]Master of Subgraph
题目大意:
一棵\(n(n\le3000)\)个结点的树,每个结点的权值为\(w_i\)。给定\(m(m\le10^5)\),对于任意\(i\in[1,m]\),问书中是否有一个连通子图的权值和等于\(i\)。
思路:
重心剖分。考虑处理当前处理出的以重心\(x\)为根的子树。首先求出当前子树的DFS序,设用\(node[i]\)表示DFS序为\(i\)的结点编号。考虑动态规划,用\(f[i][j]\)(std::bitset<M> f[N])表示包含DFS序为\(i\)的结点,是否有权值和为\(j\)的连通子图。设当前结点为\(x\),枚举子结点\(y_{1\sim k}\),则转移方程为\(f[x]=(f[y_1]\vee f[y_2]\vee\ldots\vee f[y_k])<<w[x]\)。
由于事实上对于每一个\(x\),我们并不需要知道\(f[x]\),而只需要利用它们求出\(f[root]\)的值,因此我们对于每一个\(x\)可以和上一个计算过的同级兄弟结点\(node[dfn[x]+sz[x]]\)合并。按DFS倒序枚举每一个结点\(x\),其DFS序为\(i\)。此时的状态转移方程为\(f[i]=(f[i+1]<<w[x])|f[i+sz[x]]\)。时间复杂度\(\mathcal O(\frac{nm\log n}\omega)\)。
源代码:
#include<cstdio>
#include<cctype>
#include<bitset>
#include<forward_list>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
constexpr int N=3001,M=1e5+1;
bool vis[N];
std::forward_list<int> e[N];
std::bitset<M> ans,f[N];
int n,m,w[N],size[N],sz[N],node[N],dfn[N],root,whole,min;
inline void add_edge(const int &u,const int &v) {
e[u].emplace_front(v);
e[v].emplace_front(u);
}
inline void clear() {
ans.reset();
for(register int i=1;i<=n;i++) {
vis[i]=false;
e[i].clear();
}
}
void dfs_root(const int &x,const int &par) {
size[x]=1;
int max=0;
for(auto &y:e[x]) {
if(y==par||vis[y]) continue;
dfs_root(y,x);
size[x]+=size[y];
max=std::max(max,size[y]);
}
max=std::max(max,whole-size[x]);
if(max<min) {
min=max;
root=x;
}
}
inline void get_root(const int &x,const int &sum) {
root=0;
min=n+1;
whole=sum;
dfs_root(x,0);
vis[root]=true;
}
void dfs(const int &x,const int &par) {
sz[x]=1;
dfn[x]=dfn[0]++;
node[dfn[x]]=x;
for(auto &y:e[x]) {
if(y==par||vis[y]) continue;
dfs(y,x);
sz[x]+=sz[y];
}
}
void solve(const int &x) {
dfn[0]=0;
dfs(x,0);
f[dfn[0]]=1;
for(register int i=dfn[0]-1;~i;i--) {
const int &y=node[i];
f[i]=(f[i+1]<<w[y])|f[i+sz[y]];
}
ans|=f[0];
for(auto &y:e[x]) {
if(vis[y]) continue;
get_root(y,size[y]);
solve(root);
}
}
int main() {
for(register int T=getint();T;T--) {
n=getint(),m=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
for(register int i=1;i<=n;i++) {
w[i]=getint();
}
get_root(1,n);
solve(root);
for(register int i=1;i<=m;i++) {
printf("%d",(int)ans[i]);
}
putchar('\n');
clear();
}
return 0;
}
[HDU6268]Master of Subgraph的更多相关文章
- 算法学习分析-点分治 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 ...
- 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, no ...
- 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] ...
- CCPC 2016 杭州 E. Master of Subgraph(点分治+bitset优化DP)
题目链接:http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 题意:给定一棵有 n 个结点的树和一个数 m,对于 i ∈ ...
- The 2017 China Collegiate Programming Contest, Hangzhou Site Solution
A: Super_palindrome 题面:给出一个字符串,求改变最少的字符个数使得这个串所有长度为奇数的子串都是回文串 思路:显然,这个字符串肯定要改成所有奇数位相同并且所有偶数位相同 那统计一下 ...
- 2017 CCPC杭州 题解
2017CCPC杭州题目PDF Problem A. Super-palindrome 题解: 给你一个字符串,每一步可以将一个字符替换为另一个字符,问你最少多少步可以使得,该字符串任意奇数子串为回文 ...
- ROS知识(20)----使用Master_API查询Master管理的节点话题服务内容
在一些应用中会需要获取master的uri地址,发布的话题,订阅的话题,发布的服务,节点的信息等等.这些功能我们通常可一通过rosnode list, rosnode info, rostopic l ...
随机推荐
- 马上给Meltdown和Spectre漏洞打补丁
元旦之后的第一个工作日可谓是惊喜不断,4号就传来了 Google Project Zero 等团队和个人报告的 Meltdown 和 Spectre 内核漏洞的消息,首先简单介绍一下这两个内核漏洞. ...
- ios上传图片显示方向错误问题
IOS 上传图片方向显示错误问题 问题描述 在使用苹果手机上传图片的时候,发现传完的图片显示出来方向是错误的,竖着的图片会变成横着显示(少部分安卓手机也存在这个问题) 产生原因 ios 相机加入了方向 ...
- Dom4j解析语音数据XML文档(注意ArrayList多次添加对象,会导致覆盖之前的对象)
今天做的一个用dom4j解析声音文本的xml文档时,我用ArrayList来存储每一个Item的信息,要注意ArrayList多次添加对象,会导致覆盖之前的对象:解决方案是在最后将对象添加入Array ...
- java深入解析
具体内容安排如下: Java Collections Framework概览 对Java Collections Framework,以及Java语言特性做出基本介绍. Java ArrayList源 ...
- 9张图让你明白什么叫做"一坨屎"一样的iOS垃圾代码
前言:这是一个两万余行的商业项目,但代码质量却不敢恭维! //本文永久链接,转载请注明出处:http://www.cnblogs.com/ChenYilong/p/3489939.html ...
- linux基础的基础命令操作
一.开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 操作:su - root 二.使用快捷键切换到虚拟终端2,使用普通用户身份登录,查看系统提示符 操作:ctrl ...
- Linux中实现一个简单的进度条【转】
转自:http://blog.csdn.net/yuehailin/article/details/53999288 说起进度条,其实大家常常见到,比如说你在下载视频或文件的时候,提示你当前下载进度的 ...
- SSM+Maven的JavaWeb项目中的异常的可能性
1.404 可能:1):被拦截了,即:springmvc中的controller可能不存在,可能没有被配置,可能配置出错 2):资源确实不存在 3):路径出错 2.500,程序异常,但是业务逻辑什么都 ...
- 浏览器内核测试 v0.99
操作系统: Windows 7 浏览器内核: WebKit 内核(Chrome) 内核版本是: WebKit 537.36( Chrome 49.0.2593.0 S) 完整代码: Mozilla/ ...
- AngularJS 入门教程
1. 简介:AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了.所以我做了一些工作(你也可以觉得是 ...