[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 ...
随机推荐
- 理解SetCapture、ReleaseCapture、GetCapture(控制了消息发往哪个窗口,是理解消息的关键)
理解SetCapture.ReleaseCapture.GetCapture 正常情况下,鼠标指针位于哪个窗口区域内,鼠标消息就自动发给哪个窗口.如果调用了SetCapture,之后无论鼠标的位置在哪 ...
- Java之戳中痛点 - (4)i++ 和 ++i 探究原理
先看一个例子: package com.test; public class AutoIncrement { public static void main(String[] args) { int ...
- a 标签中 title 属性样式修改
无文字描述,直接上测试页,看效果. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- eclipse配置文件内存设置
1.-Xms64m -Xmx128m 2.配置文件的修改 http://wenku.baidu.com/link?url=spM-qCe0qHdhiykzwuzp-vBtcQrVtAzYiWe8uex ...
- bzoj2683/4066 简单题
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2683 http://www.lydsy.com/JudgeOnline/problem.ph ...
- 【BZOJ】1592: [Usaco2008 Feb]Making the Grade 路面修整
[算法]动态规划DP [题解] 题目要求不严格递增或不严格递减. 首先修改后的数字一定是原来出现过的数字,这样就可以离散化. f[i][j]表示前i个,第i个修改为第j个数字的最小代价,a表示排序后数 ...
- 【洛谷 P3834】 可持久化线段树1(主席树)
题目链接 主席树=可持久化权值线段树. 如果你不会可持久化线段树,请右转 如果你不会权值线段树,请自行脑补,就是线段树维护值域里有多少个数出现. 可持久化线段树是支持查询历史版本的. 我们对每个数都进 ...
- bzoj 1301 后缀数组
比较裸的后缀数组. /************************************************************** Problem: User: BLADEVIL La ...
- concurrent
from concurrent.futures import ThreadPoolExecutor
- HDU1503(LCS,记录路径)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...