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是质数,所 ...
随机推荐
- TKT中文编程语言简介
TKT中文编程语言简介 TKT语言是新型的类似自然语言的汉语编程语言. 它是基于新的语言设计思想创造的语言,和现存的易语言.习语言.O语言.汉编等中文编程语言没有关系. TKT语言特点一: 中文编程 ...
- sed命令详解
搜索 纠正错误 添加实例 sed 功能强大的流式文本编辑器 补充说明 sed 是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时 ...
- 创建table并实现ID自增长
① create table p_user( id number(10) not null primary key, name varchar2(3 ...
- 【转】linux 设置用户id 设置组id
linux 设置用户id 设置组id 转自 linux 设置用户id 设置组id 最近看apue,简单记录对设置用户id理解(设置组id同理). 1. 相关的id好像很多,共有哪些? 文件2个 ...
- Oracle的SQL语句中的变量替换
一.问题描述 如下SQL: INSERT INTO tmp(val)VALUES('a&b'); 执行过程中会出现如下提示: 点击"确定"过后我们查看表中的数据: b后面的 ...
- nginx访问量统计
1.根据访问IP统计UV awk '{print $1}' access.log|sort | uniq -c |wc -l 2.统计访问URL统计PV awk '{print $7}' acces ...
- Selenium Xpath Tutorials - Identifying xpath for element with examples to use in selenium
Xpath in selenium is close to must required. XPath is element locator and you need to provide xpath ...
- iOS 对象的内存管理细节
通过类创建对象 1.创建对象时,开辟存储空间,通过new方法创建的对象会在 堆 内存中开辟一块存储空间 2初始化所有属性都在堆内存中完成 3.返回值真地址,指针在栈内存中,指针指向的地址是堆里创建对象 ...
- Cocos2dx
初玩Cocos2dx,多多包涵. 感觉版本之间的差异比较大,相对前面的版本来说,3.X更容易上手,更方便了. 一.安装python.我的python-2.7.3.配置环境变量 系统变量里:在Path里 ...
- css 上下滚动效果
<html> <head> <style> .scroll{ overflow:hidden; width:100%; } .scrollout{ height:2 ...