热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

hdu5909TreeCutting——点分治(树形DP转为序列DP)

题目:http:acm.hdu.edu.cnshowproblem.php?pid5909点分治的话,每次要做一次树形DP;但时间应该是s

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909

点分治的话,每次要做一次树形DP;但时间应该是 siz*m2 的。可以用 FWT 变成 siz*mlogm ,但这里写的是把树变成序列来 DP 的方法,应该是 nlogn*m 的。

树上的一个点,如果选,就可以选它的孩子,所以它向它的第一个孩子连边;如果不选,就会跳到它的下一个兄弟或者是父亲的下一个兄弟之类的,向那边连一条边。

做出树的 dfs 序,把边都连在 dfs 序上;其实那个第一条边一定连向自己 dfs 序+1,即使自己没有孩子也是符合的,所以可以不用连了;第二条边可以通过传父亲的连边对象来解决。

#include
#include

#include

using namespace std;
const int N=1005,M=1025,mod=1e9+7;
int T,n,m,w[N],hd[N],xnt,to[N<<1],nxt[N<<1],siz[N],rt,mn;
int dfn[N],tot,sta[N],top,f[N][M],g[N],nt[N],ans[M]; bool vis[N];
int rdn()
{
int ret&#61;0;bool fx&#61;1;char ch&#61;getchar();while(ch>&#39;9&#39;||ch<&#39;0&#39;){if(ch&#61;&#61;&#39;-&#39;)fx&#61;0;ch&#61;getchar();}while(ch>&#61;&#39;0&#39;&&ch<&#61;&#39;9&#39;)ret&#61;ret*10&#43;ch-&#39;0&#39;,ch&#61;getchar();return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return aa:b;}
void upd(int &x){x>&#61;mod?x-&#61;mod:0;}
void init()
{xnt
&#61;0;memset(hd,0,sizeof hd);memset(ans,0,sizeof ans); memset(vis,0,sizeof vis);
}
void add(int x,int y){to[&#43;&#43;xnt]&#61;y;nxt[xnt]&#61;hd[x];hd[x]&#61;xnt;}
void getrt(int cr,int fa,int s)
{siz[cr]
&#61;1; int mx&#61;0;for(int i&#61;hd[cr],v;i;i&#61;nxt[i])if(!vis[v&#61;to[i]]&&v!&#61;fa){getrt(v,cr,s);siz[cr]&#43;&#61;siz[v];mx&#61;Mx(mx,siz[v]);}mx&#61;Mx(mx,s-siz[cr]);if(mxcr;
}
void dfs(int cr,int fa)
{dfn[cr]
&#61;&#43;&#43;tot;g[tot]&#61;w[cr];for(int i&#61;hd[cr],v;i;i&#61;nxt[i])if(!vis[v&#61;to[i]]&&v!&#61;fa)dfs(v,cr);
}
void dfsx(int cr,int fa,int lst)
{nt[dfn[cr]]
&#61;lst;int l&#61;top&#43;1;for(int i&#61;hd[cr],v;i;i&#61;nxt[i])if(!vis[v&#61;to[i]]&&v!&#61;fa)sta[&#43;&#43;top]&#61;v;int r&#61;top;for(int i&#61;hd[cr],v,p0&#61;l;i;i&#61;nxt[i])if(!vis[v&#61;to[i]]&&v!&#61;fa){dfsx(v,cr,p0&#61;&#61;r?lst:dfn[sta[p0&#43;1]]);p0&#43;&#43;;}
}
void solve(int cr,int s)
{vis[cr]
&#61;1;tot&#61;0;dfs(cr,0);top&#61;0;dfsx(cr,0,s&#43;1);for(int i&#61;1;i<&#61;s&#43;1;i&#43;&#43;)memset(f[i],0,sizeof f[i]);f[1][0]&#61;1;for(int i&#61;1;i<&#61;s;i&#43;&#43;)for(int j&#61;0;j){if(!f[i][j])continue;f[i&#43;1][j^g[i]]&#43;&#61;f[i][j];upd(f[i&#43;1][j^g[i]]);f[nt[i]][j]&#43;&#61;f[i][j];upd(f[nt[i]][j]);}f[s&#43;1][0]--;//dec the emptyfor(int j&#61;0,k&#61;s&#43;1;jf[k][j],upd(ans[j]);for(int i&#61;hd[cr],v,ts;i;i&#61;nxt[i])if(!vis[v&#61;to[i]]){ts&#61;(siz[cr]>siz[v]?siz[v]:s-siz[cr]);mn&#61;N;getrt(v,cr,ts);solve(rt,ts);}
}
int main()
{T
&#61;rdn();while(T--){n&#61;rdn();m&#61;rdn();for(int i&#61;1;i<&#61;n;i&#43;&#43;)w[i]&#61;rdn();init();for(int i&#61;1,u,v;irdn(),add(u,v),add(v,u);mn&#61;N;getrt(1,0,n);solve(rt,n);for(int i&#61;0,j&#61;m-1;i"%d ",ans[i]);printf("%d\n",ans[m-1]);}return 0;
}

 


转载于:https://www.cnblogs.com/Narh/p/10182918.html


推荐阅读
  • HDU1085 捕获本·拉登!
    问题描述众所周知,本·拉登是一位臭名昭著的恐怖分子,他已失踪多年。但最近有报道称,他藏匿在中国杭州!虽然他躲在杭州的一个洞穴中不敢外出,但近年来他因无聊而沉迷于数学问题,并声称如果有人能解出他的题目,他就自首。 ... [详细]
  • 抽象工厂模式 c++
    抽象工厂模式包含如下角色:AbstractFactory:抽象工厂ConcreteFactory:具体工厂AbstractProduct:抽象产品Product:具体产品https ... [详细]
  • ZOJ 2760 - 最大流问题
    题目链接:How Many Shortest Paths。题目描述:给定一个包含n个节点的有向图,通过一个n*n的矩阵来表示。矩阵中的a[i][j]值为-1表示从节点i到节点j无直接路径;否则,该值表示从i到j的路径长度。输入起点vs和终点vt,计算从vs到vt的所有不共享任何边的最短路径数量。如果起点和终点相同,则输出无穷大。 ... [详细]
  • 2022年4月15日的算法练习题,包括最长公共子序列和线段树的应用。 ... [详细]
  • 本文探讨了Lua中元表和元方法的使用,通过具体的代码示例展示了如何利用这些特性来实现类似C语言中的运算符重载功能。 ... [详细]
  • 拖拉切割直线 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • UVA 401 - 镜像回文字符串
    本题探讨了如何判断一个字符串是否为普通回文、镜像回文或两者都不是。通过特定的字符映射表来实现字符串的镜像转换,并根据转换后的结果进行分类。 ... [详细]
  • SQLite是一种轻量级的关系型数据库管理系统,尽管体积小巧,却能支持高达2TB的数据库容量,每个数据库以单个文件形式存储。本文将详细介绍SQLite在Android开发中的应用,包括其数据存储机制、事务处理方式及数据类型的动态特性。 ... [详细]
  • 3144:[Hnoi2013]切糕TimeLimit:10SecMemoryLimit:128MBSubmit:1261Solved:700[Submit][St ... [详细]
  • 题目描述墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令ÿ ... [详细]
  • [编程题] LeetCode上的Dynamic Programming(动态规划)类型的题目
    继上次把backTracking的题目做了一下之后:backTracking,我把LeetCode的动态规划的题目又做了一下,还有几道比较难的Medium的题和Hard的题没做出来,后面会继续 ... [详细]
  • 本题要求计算从起点到终点所有最短路径的总权重,使用SPFA算法进行求解。 ... [详细]
  • 题目描述:给定 n 把雨伞和 m 个人,t 分钟后开始下雨。求在每个人只能使用一把雨伞的情况下,最多有多少人可以拿到雨伞。 ... [详细]
  • 探讨了生成时间敏感的一次性伪随机密码的方法,旨在通过加入时间因素防止重放攻击。 ... [详细]
author-avatar
dtssv90623
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有