HDU 5977 Garden of Eden (树分治+状态压缩)
题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点?
析:对于路径,就是两类,第一种情况,就是跨过根结点,第二种是不跨过根结点,分别讨论就好,由于结点比较大,所以采用分治来进行处理,优先选取重点作为划分的依据。
代码如下:
- #pragma comment(linker, "/STACK:1024000000,1024000000")
- #include <cstdio>
- #include <string>
- #include <cstdlib>
- #include <cmath>
- #include <iostream>
- #include <cstring>
- #include <set>
- #include <queue>
- #include <algorithm>
- #include <vector>
- #include <map>
- #include <cctype>
- #include <cmath>
- #include <stack>
- #include <sstream>
- #include <list>
- #include <assert.h>
- #define debug() puts("++++");
- #define gcd(a, b) __gcd(a, b)
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- #define fi first
- #define se second
- #define pb push_back
- #define sqr(x) ((x)*(x))
- #define ms(a,b) memset(a, b, sizeof a)
- #define sz size()
- #define pu push_up
- #define pd push_down
- #define FOR(x,n) for(int i = (x); i < (n); ++i)
- #define freopenr freopen("in.txt", "r", stdin)
- #define freopenw freopen("out.txt", "w", stdout)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- typedef pair<int, int> P;
- const int INF = 0x3f3f3f3f;
- const double inf = 1e20;
- const double PI = acos(-1.0);
- const double eps = 1e-8;
- const int maxn = 50000 + 10;
- const LL mod = 1e9 + 7;
- const int dr[] = {-1, 0, 1, 0};
- const int dc[] = {0, 1, 0, -1};
- const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
- int n, m;
- const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- inline bool is_in(int r, int c) {
- return r > 0 && r <= n && c > 0 && c <= m;
- }
- int all;
- struct Edge{
- int to, next;
- };
- Edge edge[maxn<<1];
- int head[maxn], cnt;
- int val[maxn];
- void addEdge(int u, int v){
- edge[cnt].to = v;
- edge[cnt].next = head[u];
- head[u] = cnt++;
- }
- int root, num, f[maxn];
- LL dp[1<<10];
- int sum[maxn];
- bool vis[maxn];
- LL ans;
- void dfs_for_root(int u, int fa){
- sum[u] = 1; f[u] = 0;
- for(int i = head[u]; ~i; i = edge[i].next){
- int v = edge[i].to;
- if(v == fa || vis[v]) continue;
- dfs_for_root(v, u);
- sum[u] += sum[v];
- f[u] = max(f[u], sum[v]);
- }
- f[u] = max(f[u], num - sum[u]);
- if(f[root] > f[u]) root = u;
- }
- void dfs_for_color(int u, int fa, int s){
- for(int i = head[u]; ~i; i = edge[i].next){
- int v = edge[i].to;
- if(v == fa || vis[v]) continue;
- ++dp[s|1<<val[v]];
- dfs_for_color(v, u, s|1<<val[v]);
- }
- }
- LL solve(int u, int s){
- ms(dp, 0);
- ++dp[s];
- dfs_for_color(u, -1, s);
- LL ans = 0;
- for(int i = 0; i <= all; ++i){
- if(!dp[i]) continue;
- int tmp = 0;
- tmp += dp[all];
- for(int j = i; j; j = (j-1)&i)
- tmp += dp[all^j];
- ans += (LL)tmp * dp[i];
- }
- return ans;
- }
- void dfs_for_ans(int u){
- ans += solve(u, 1<<val[u]);
- vis[u] = true;
- for(int i = head[u]; ~i; i = edge[i].next){
- int v = edge[i].to;
- if(vis[v]) continue;
- ans -= solve(v, 1<<val[u]|1<<val[v]);
- root = 0;
- f[0] = num = sum[v];
- dfs_for_root(v, u);
- dfs_for_ans(root);
- }
- }
- int main(){
- while(scanf("%d %d", &n, &m) == 2){
- for(int i = 1; i <= n; ++i){
- scanf("%d", val+i);
- --val[i];
- }
- all = (1<<m) - 1;
- ms(head, -1); cnt = 0;
- for(int i = 1; i < n; ++i){
- int u, v;
- scanf("%d %d", &u, &v);
- addEdge(u, v);
- addEdge(v, u);
- }
- ms(vis, 0);
- root = 0; ans = 0LL;
- f[0] = num = n;
- dfs_for_root(1, -1);
- dfs_for_ans(root);
- printf("%I64d\n", ans);
- }
- return 0;
- }
HDU 5977 Garden of Eden (树分治+状态压缩)的更多相关文章
- 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 ...
- 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(点分治+状压)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977 题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp ...
- HDU 5977 Garden of Eden
题解: 路径统计比较容易想到点分治和dp dp的话是f[i][j]表示以i为根,取了i,颜色数状态为j的方案数 但是转移这里如果暴力转移就是$(2^k)^2$了 于是用FWT优化集合或 另外http: ...
- HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)
CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...
- HDU - 5977 Garden of Eden (树形dp+容斥)
题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...
- HDU-5977 - Garden of Eden 点分治
HDU - 5977 题意: 给定一颗树,问树上有多少节点对,节点对间包括了所有K种苹果. 思路: 点分治,对于每个节点记录从根节点到这个节点包含的所有情况,类似状压,因为K<=10.然后处理每 ...
- HDU 3605:Escape(最大流+状态压缩)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...
- HDU 2809 God of War(DP + 状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2809 题目大意:给出战神吕布的初始攻击力ATI.防御力DEF.生命值HP.每升一级增加的攻击力In_A ...
随机推荐
- 安装nagios检测hadoop
Nagios是常用的系统监控工具,提供了很多基本服务的监控脚本,如HTTP,MYSQL等,同时具有不错的可扩展性,自己可定制针对特定参数的监控脚本以及报警的方式. 我现在有三台机器:192.168.0 ...
- 第十章 Secret & Configmap(下)
10.4 ConfigMap Secret可以为Pod提供密码.Token.私钥等敏感数据:对于一些非敏感数据,比如一些配置信息,则可以用ConfigMap. configMap的使用方式与Secre ...
- 浅谈PHP面向对象编程(九、设计模式)
9.0 设计模式 在编写程序时经常会遇到一此典型的问题或需要完成某种特定需求,设计模式就是针对这些问题和需求,在大量的实践中总结和理论化之后优选的代码结构编程风格,以及解决问题的思考方式. 设计模式就 ...
- CDH5.10.0 离线安装(共3节点) 转
1.安装方式 CDH的离线部署安装,即Parcel包(推荐) 2.角色规划 三个节点对应的角色: 3.基本环境配置(在每个节点上都要配置) (1)关闭防火墙 #/etc/init.d/iptables ...
- ArraySort--冒泡排序、选择排序、插入排序工具类demo
public class ArraySort { private long[] a; private int nElems; public ArraySort(int max){ a=new long ...
- 【转】Android开发笔记——圆角和边框们
原文地址:http://blog.xianqu.org/2012/04/android-borders-and-radius-corners/ Android开发笔记——圆角和边框们 在做Androi ...
- g++ 4.4.7 template 没问题,前面应该程序问题!!
- Ubuntu TIP
recovery进系统硬盘是挂载为“只读”的,要想改文件需要remount / 并且添加“w”(写权限). 进一次crub,再root进入 折腾几次似乎就可以编辑磁盘上的文件了
- Microsoft.Office.Core 引用以及 Microsoft.Office.Core.MsoTriState 的问题
转自原文 xiaoanian, Microsoft.Office.Core 引用以及 Microsoft.Office.Core.MsoTriState 的问题 因为要做一个提取ppt文字的工程,第一 ...
- BurpSuite系列(十二)----User options模块(用户选择)
一.简介 User options模块主要用来配置一些常用的选项. 二.模块说明 User options主要由4个模块组成: 1.Connections 连接 2.SSL 3.Display 4 ...