题目链接:

Garden of Eden

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 210    Accepted Submission(s): 75

Problem 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种颜色;
 
思路:
 
一开始想用树形dp搞,然而MLE了,所以就是树分治了,模板往上一套就好了;注意每次寻找到了root就保存下来;
 
AC代码:
 
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=5e4+5;
int n,k,fk,a[maxn],p[13];
int siz[maxn],son[maxn],vis[maxn],root,MAX,cnt,num[1030],d[maxn],cn=0,head[maxn];
LL ans=0;
struct Edge
{
int to,next;
}edge[2*maxn];
inline void add_edge(int from,int to)
{
edge[cn].to=to;
edge[cn].next=head[from];
head[from]=cn++;
}
inline void init()
{
cn=0;
fk=(1<<k)-1;
ans=0;
for(int i=0;i<=n;i++)vis[i]=0;
memset(head,-1,sizeof(head));
}
void get_siz(int cur,int fa)
{
siz[cur]=1;
son[cur]=0;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int x=edge[i].to;
if(x==fa||vis[x])continue;
get_siz(x,cur);
siz[cur]+=siz[x];
if(siz[x]>son[cur])son[cur]=siz[x];
}
}
void find_root(int cur,int fa,int rt)
{
if(siz[rt]-siz[cur]>son[cur])son[cur]=siz[rt]-siz[cur];
if(son[cur]<MAX)MAX=son[cur],root=cur;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int x=edge[i].to;
if(x==fa||vis[x])continue;
find_root(x,cur,rt);
}
}
void get_state(int cur,int fa,int sta)
{
d[cnt++]=sta;
num[sta]++;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int x=edge[i].to;
if(vis[x]||x==fa)continue;
get_state(x,cur,a[x]|sta);
}
}
LL cal(int cur,int sta)
{
cnt=0;
memset(num,0,sizeof(num));
get_state(cur,0,sta);
for(int i=0;i<k;i++)
{
for(int j=fk;j>=0;j--)
{
if(!(p[i]&j))num[j]+=num[j|p[i]];
}
}
LL ret=0;
for(int i=0;i<cnt;i++)ret=ret+num[fk^d[i]];
return ret;
}
void dfs(int cur)
{
MAX=n;
get_siz(cur,0);
find_root(cur,0,cur);
int Root=root;
ans=ans+cal(root,a[Root]);
vis[root]=1;
for(int j=head[Root];j!=-1;j=edge[j].next)
{
int x=edge[j].to;
if(vis[x])continue;
ans=ans-cal(x,(a[x]|a[Root]));
dfs(x);
}
}
int main()
{
p[0]=1;for(int i=1;i<=11;i++)p[i]=p[i-1]*2;
while(scanf("%d%d",&n,&k)!=EOF)
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]=p[a[i]-1];
}
int u,v;
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(1);
printf("%lld\n",ans);
}
return 0;
}

  

hdu-5977 Garden of Eden(树分治)的更多相关文章

  1. HDU 5977 Garden of Eden (树分治+状态压缩)

    题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点? 析:对于路径,就是两类,第一种情况,就是跨过根结点,第二种是不跨过根结点,分别讨论就好 ...

  2. 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 ...

  3. hdu 5977 Garden of Eden(点分治+状压)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977 题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp ...

  4. HDU 5977 Garden of Eden

    题解: 路径统计比较容易想到点分治和dp dp的话是f[i][j]表示以i为根,取了i,颜色数状态为j的方案数 但是转移这里如果暴力转移就是$(2^k)^2$了 于是用FWT优化集合或 另外http: ...

  5. HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)

    CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...

  6. HDU - 5977 Garden of Eden (树形dp+容斥)

    题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...

  7. HDU-5977 - Garden of Eden 点分治

    HDU - 5977 题意: 给定一颗树,问树上有多少节点对,节点对间包括了所有K种苹果. 思路: 点分治,对于每个节点记录从根节点到这个节点包含的所有情况,类似状压,因为K<=10.然后处理每 ...

  8. HDU5977 Garden of Eden(树的点分治)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...

  9. HDU 4871 Shortest-path tree 最短路 + 树分治

    题意: 输入一个带权的无向连通图 定义以顶点\(u\)为根的最短路生成树为: 树上任何点\(v\)到\(u\)的距离都是原图最短的,如果有多条最短路,取字典序最小的那条. 然后询问生成树上恰好包含\( ...

随机推荐

  1. C# Enum Name String Description之间的相互转换

    最近工作中经常用到Enum中Value.String.Description之间的相互转换,特此总结一下. 1.首先定义Enum对象 public enum Weekday { [Descriptio ...

  2. C#正则表达式验证

    public class VerifyUtil { /// <summary> /// 判断输入的字符串只包含汉字 /// </summary> /// <param n ...

  3. socket编程-java

    一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...

  4. Home / Python MySQL Tutorial / Calling MySQL Stored Procedures in Python Calling MySQL Stored Procedures in Python

    f you are not familiar with MySQL stored procedures or want to review it as a refresher, you can fol ...

  5. SqlServer-无限递归树状图结构设计和查询

    在现实生活中,公司的部门设计会涉及到很多子部门,然后子部门下面又存在子部门,形成类似判断的树状结构,比如说评论楼中楼的评论树状图,职位管理的树状图结构等等,实现类似的树状图数据结构是在开发中经常出现的 ...

  6. java Io流输出指定文件的内容

    package com.hp.io; import java.io.*; public class  BufferedReaderTest{ /** *@param   想想 */ public st ...

  7. No.024:Swap Nodes in Pairs

    问题: Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1-> ...

  8. php实现设计模式之 工厂方法模式

    <?php /* * *工厂方法模式,创建型模式 定义一个用于创建对象的工厂接口,让子类决定实例化哪一个类.Factory Method使用一个类的实例化延迟到其子类 * * 四个角色: * 工 ...

  9. Asp.net mvc5开源项目"超级冷笑话"

    业务时间做了个小网站,超级冷笑话,地址:http://www.superjokes.cn/ 开发技术: asp.net mvc5 +SQLServer2012 ORM:NPoco 用了简单的三层结构 ...

  10. Linux安全基础:awk命令的使用

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...