HDU5977 Garden of Eden(树的点分治)
题目
Source
http://acm.hdu.edu.cn/showproblem.php?pid=5977
Description
When God made the first man, he put him on a beautiful garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was asleep one night, God took a rib from him and made Eve beside him. God said to them, “here in the Garden, you can do everything, but you cannot eat apples from the tree of knowledge.”
One day, Satan came to the garden. He changed into a snake and went to live in the tree of knowledge. When Eve came near the tree someday, the snake called her. He gave her an apple and persuaded her to eat it. Eve took a bite, and then she took the apple to Adam. And Adam ate it, too. Finally, they were driven out by God and began a hard journey of life.
The above is the story we are familiar with. But we imagine that Satan love knowledge more than doing bad things. In Garden of Eden, the tree of knowledge has n apples, and there are k varieties of apples on the tree. Satan wants to eat all kinds of apple to gets all kinds of knowledge.So he chooses a starting point in the tree,and starts walking along the edges of tree,and finally stops at a point in the tree(starting point and end point may be same).The same point can only be passed once.He wants to know how many different kinds of schemes he can choose to eat all kinds of apple. Two schemes are different when their starting points are different or ending points are different.
Input
There are several cases.Process till end of input.
For each case, the first line contains two integers n and k, denoting the number of apples on the tree and number of kinds of apple on the tree respectively.
The second line contains n integers meaning the type of the i-th apple. Types are represented by integers between 1 and k .
Each of the following n-1 lines contains two integers u and v,meaning there is one edge between u and v.1≤n≤50000, 1≤k≤10
Output
For each case output your answer on a single line.
Sample Input
3 2
1 2 2
1 2
1 3
Sample Output
6
分析
题目大概说一棵树,各个结点都有一个数字(<=k),然后问有几条路径使得路径上所有结点包含了1到k的所有数字。
路径,自然想到树分治解决,因为任何一条路径都在以某个点为根的子树中且过那条根的链。
- 考虑cnt[S]记录已经统计获得的数字集合为S的路径数量。。
- 不过这样会发现,新的路径信息与其合并更新答案时,还要枚举它的补集以及补集的超集,这时间复杂度不太好。。
- 所以直接cnt[S]表示已经统计获得的数字集合为S以及S的超集的路径数量。。
- 现在问题是新的路径信息如何合并到cnt[S]中,其实只要枚举所有新的路径信息再枚举所有集合状态就OK了,时间复杂度由主定理可知是$O(nlogn2^k)$。。简单粗暴就过了。。
另外。。注意路径的起点和终点是可以一样的。。
代码
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define INF (1<<30)
- #define MAXN 50010
- struct Edge{
- int v,next;
- }edge[MAXN<<1];
- int NE,head[MAXN];
- void addEdge(int u,int v){
- edge[NE].v=v; edge[NE].next=head[u];
- head[u]=NE++;
- }
- bool vis[MAXN];
- int size[MAXN];
- void getsize(int u,int fa){
- size[u]=1;
- for(int i=head[u]; i!=-1; i=edge[i].next){
- int v=edge[i].v;
- if(vis[v] || v==fa) continue;
- getsize(v,u);
- size[u]+=size[v];
- }
- }
- int mini,cen;
- void getcen(int u,int fa,int &tot){
- int res=tot-size[u];
- for(int i=head[u]; i!=-1; i=edge[i].next){
- int v=edge[i].v;
- if(vis[v] || v==fa) continue;
- res=max(res,size[v]);
- getcen(v,u,tot);
- }
- if(res<mini){
- mini=res;
- cen=u;
- }
- }
- int getcen(int u){
- getsize(u,u);
- mini=INF;
- getcen(u,u,size[u]);
- return cen;
- }
- long long cnt[1024];
- int rec[MAXN],rn;
- int type,val[MAXN];
- long long ans;
- void conqur_dfs(int u,int fa,int s){
- ans+=cnt[(~s)&((1<<type)-1)];
- rec[rn++]=s;
- for(int i=head[u]; i!=-1; i=edge[i].next){
- int v=edge[i].v;
- if(fa==v || vis[v]) continue;
- conqur_dfs(v,u,s|(1<<val[v]));
- }
- }
- void conqur(int u){
- memset(cnt,0,sizeof(cnt));
- cnt[0]=1;
- for(int i=head[u]; i!=-1; i=edge[i].next){
- int v=edge[i].v;
- if(vis[v]) continue;
- rn=0;
- conqur_dfs(v,v,(1<<val[u])|(1<<val[v]));
- for(int j=0; j<rn; ++j){
- for(int k=0; k<(1<<type); ++k){
- if((rec[j]|k)==rec[j]) ++cnt[k];
- }
- }
- }
- }
- void divide(int u){
- u=getcen(u);
- vis[u]=1;
- conqur(u);
- for(int i=head[u]; i!=-1; i=edge[i].next){
- int v=edge[i].v;
- if(vis[v]) continue;
- divide(v);
- }
- }
- int main(){
- int n;
- while(~scanf("%d%d",&n,&type)){
- for(int i=1; i<=n; ++i){
- scanf("%d",val+i);
- --val[i];
- }
- NE=0;
- memset(head,-1,sizeof(head));
- int a,b;
- for(int i=1; i<n; ++i){
- scanf("%d%d",&a,&b);
- addEdge(a,b);
- addEdge(b,a);
- }
- memset(vis,0,sizeof(vis));
- ans=0;
- divide(1);
- ans*=2;
- if(type==1) ans+=n;
- printf("%lld\n",ans);
- }
- return 0;
- }
HDU5977 Garden of Eden(树的点分治)的更多相关文章
- hdu-5977 Garden of Eden(树分治)
题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- HDU-5977 - Garden of Eden 点分治
HDU - 5977 题意: 给定一颗树,问树上有多少节点对,节点对间包括了所有K种苹果. 思路: 点分治,对于每个节点记录从根节点到这个节点包含的所有情况,类似状压,因为K<=10.然后处理每 ...
- HDU 5977 Garden of Eden (树分治+状态压缩)
题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点? 析:对于路径,就是两类,第一种情况,就是跨过根结点,第二种是不跨过根结点,分别讨论就好 ...
- HDU5977 Garden of Eden 【FMT】【树形DP】
题目大意:求有所有颜色的路径数. 题目分析:参考codeforces997C,先利用基的FMT的性质在$O(2^k)$做FMT,再利用只还原一位的特点在$O(2^k)$还原,不知道为什么网上都要点分治 ...
- hdu5977 Garden of Eden
都不好意思写题解了 跑了4000多ms 纪念下自己A的第二题 (我还有一道freetour II wa20多发没A...呜呜呜 #include<bits/stdc++.h> using ...
- HDU 5977 Garden of Eden(点分治求点对路径颜色数为K)
Problem Description When God made the first man, he put him on a beautiful garden, the Garden of Ede ...
- Garden of Eden
Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- uva10001 Garden of Eden
Cellular automata are mathematical idealizations of physical systems in which both space and time ar ...
- HDU4812 D Tree(树的点分治)
题目大概说给一棵有点权的树,输出字典序最小的点对,使这两点间路径上点权的乘积模1000003的结果为k. 树的点分治搞了.因为是点权过根的两条路径的LCA会被重复统计,而注意到1000003是质数,所 ...
随机推荐
- CSS3教程:box-sizing属性的理解
说到 IE 的 bug,一个臭名昭著的例子是它对于“盒模型”的错误解释:在 IE5.x 以及 Quirks 模式的 IE6/7 中,将 border 与 padding 都包含在 width 之内.这 ...
- css3动画第一式--简单翻滚
在w3cschool上面查阅css3的动画语法手册时,发现“css3 动画”栏目首页放了一个翻滚的div动画案例,觉得挺好看的,于是就自己模仿着写了一下,感觉还行O(∩_∩)O哈哈~ 查看原地址 下面 ...
- less入门
less入门 安装 首先安装node,执行命令 node install -g less安装完成后可以在任意窗口中使用lessc命令,将.less文件编译成css文件. 变量 可以像其他语言一样声明变 ...
- 我常用的那些linux命令
我常用的那些linux命令 用linux也有些年头了,说来也忏愧,说是有些年头了,其实也还是个不长进的主.记得第一次接触linux是boss跟我说的怎么操作,什么编辑模式,按i,a,o进入编辑模式.在 ...
- jquery.extend
经常在插件中看到jquery.extend 方法,最近在尝试写一些简单的插件,顺便研究一下这个方法. 原文:http://www.cnblogs.com/RascallySnake/archive/2 ...
- JSP复习整理(四)Cookie
一.useCookie.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...
- 使用NPOI读取Excel报错ICSharpCode.SharpZipLib.Zip.ZipException:Wrong Local header signature
写了一个小程序利用NPOI来读取Excel,弹出这样的报错: ICSharpCode.SharpZipLib.Zip.ZipException:Wrong Local header signature ...
- 常用类string的用法
在Java中string是我们用的很多的一种类,下面就来说说string类中经常用到的一些方法. 1.string与数组相关的方法: 比如:string str = "fsafdsafdas ...
- 解决css3毛玻璃效果(blur)有白边问题
做一个登录页,全屏背景图毛玻璃效果,实现方法如下: HTML: <body> <div class="login-wrap"> <div class= ...
- Myeclipse导包总是报错,jar包路径都没问题
是访问限制报错. 方法一: 全局属性Project>preferences>java>Compiler>Errors/Warnings>把右侧的[Deprecated a ...