热门标签 | 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


推荐阅读
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社区 版权所有