题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977

题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp,这里只要稍微改一下模版就行了。还有注意一下这里的cau状态枚举然后就没什么了

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int M = 5e4 + 10;
struct Edge {int v , next;
}edge[M << 1];
int head[M] , e , Size , root , n , k , a[M] , ssr;
ll ans;
bool vis[M];
void init() {memset(head , -1 , sizeof(head));memset(vis , false , sizeof(vis));ans = 0;e = 0;ssr = ((1 << k) - 1);
}
void add(int u , int v) {edge[e].v = v;edge[e].next = head[u];head[u] = e++;
}
int size[M] , mx[M];
ll Hash[1025];
void dfs_size(int u , int pre) {size[u] = 1;mx[u] = 0;for(int i = head[u] ; i != -1 ; i = edge[i].next) {int v = edge[i].v;if(v == pre || vis[v]) continue;dfs_size(v , u);size[u] += size[v];mx[u] = max(mx[u] , size[v]);}
}
void dfs_root(int r , int u , int pre) {mx[u] = max(mx[u] , size[r] - size[u]);if(mx[u] < Size) Size = mx[u] , root = u;for(int i = head[u] ; i != -1 ; i = edge[i].next) {int v = edge[i].v;if(v == pre || vis[v]) continue;dfs_root(r , v , u);}
}
void get_root(int u , int pre) {dfs_size(u , pre);dfs_root(u , u , pre);
}
int num , State[M];
void find_state(int u , int pre , int state) {State[num++] = state;for(int i = head[u] ; i != -1 ; i = edge[i].next) {int v = edge[i].v;if(vis[v] || v == pre) continue;find_state(v , u , state | (1 << a[v]));}
}
ll cau(int u , int state) {num = 0;find_state(u , -1 , state);memset(Hash , 0 , sizeof(Hash));ll sum = 0;for(int i = 0 ; i < num ; i++) Hash[State[i]]++;for(int i = 0 ; i < num ; i++) {Hash[State[i]]--;sum += Hash[ssr];//这里由于是枚举时0枚举不到所以先加上ssr^0.for (int s0 = State[i]; s0; s0 = (s0 - 1) & State[i])sum += Hash[((1 << k) - 1) ^ s0];Hash[State[i]]++;}return sum;
}
void dfs(int u) {Size = n;get_root(u , -1);ans += cau(root , (1 << a[root]));vis[root] = true;int rt = root;for(int i = head[root] ; ~i ; i = edge[i].next) {int v = edge[i].v;if(vis[v]) continue;ans -= cau(v , (1 << a[rt]) | (1 << a[v]));dfs(v);}
}
int main() {while(scanf("%d%d" , &n , &k) != EOF) {init();for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i]) , a[i]--;for(int i = 0 ; i < n - 1 ; i++) {int u , v;scanf("%d%d" , &u , &v);add(u , v);add(v , u);}if (k == 1) {printf("%lld\n", (ll)n * (ll)n);continue;}dfs(1);printf("%lld\n" , ans);}return 0;
}

转载于:https://www.cnblogs.com/TnT2333333/p/7745410.html

hdu 5977 Garden of Eden(点分治+状压)相关推荐

  1. *【HDU - 4272 】LianLianKan (dfs 或 状压dp,贪心不行)

    题干: I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new ...

  2. 【HDU - 2809】 God of War(状压dp)

    题干: At 184~280 A.D ,there were many kingdoms in China. Three strongest among them are "Wei" ...

  3. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  4. hdu 6086 Rikka with String(AC自动机+状压dp)

    题目链接:hdu 6086 Rikka with String 题意: 给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]≠s[|s|−i+1] for all i∈[1,|s|] ,长度 ...

  5. hdu 4568 Hunter bfs建图+TSP状压DP

    想AC的人请跳过这一段... 题目应该都能读懂.但是个人觉得这题出的很烂,意思太模糊了. 首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手. 因为我想到了这几 ...

  6. HDU - 1429 胜利大逃亡(续) (BFS+状压)

    题目链接 思路 因为新拿到一把钥匙所以相同位置可以重复走,一共10把钥匙二进制表示拿到的钥匙,判断下个位置是否可以走. #include <bits/stdc++.h> const int ...

  7. HDU - 3341 Lost's revenge(AC自动机+状压dp)

    题目链接:点击查看 题目大意:给出 n 个模式串,最后给出一个匹配串,问如何重新排列匹配串,可以使得匹配串尽可能多的匹配模式串 题目分析:因为是模式串和匹配串的匹配,所以考虑AC自动机,因为数据范围比 ...

  8. HDU 6321 Problem C. Dynamic Graph Matching (状压dp)

    题意:给定一个N个点的零图,M次操作,添加或删除一条边,每一次操作以后,打印用1,2,-N/2条边构成的匹配数. 分析:因为N的范围很小,所以可以把点的枚举状态用二进制表示集合.用一维数组dp[S]表 ...

  9. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

最新文章

  1. python 数据逐个验证_在python中验证数据的最佳方法是什么?
  2. c语言把一个数组赋值给另一个数组_如何把一个固定数组的值传递给另外一个数组...
  3. K8s 从懵圈到熟练-集群伸缩原理
  4. 程序员必须掌握的英语单词
  5. 【网址收藏】k8s zookeeper-operator示例
  6. 小米手机60帧录屏_手机录屏怎样只录手机内部声音不录入外部声音?教你三种方法,一定能帮到你...
  7. python使用os.listdir和os.walk获得文件的路径
  8. el-tree与el-transfer结合成树形穿梭框(tree-transfer)
  9. Oracle数据库的创建、数据导入导出
  10. python之父的名字-Python 常见双下划线关键字的用法
  11. php 小墙 垃圾评论,关于php过滤垃圾评论
  12. SosoApi使用说明-基本操作文档
  13. AI人脸识别技术当今的发展
  14. apk分包思路(一)meta-data
  15. MIGO结合NFT技术带来全新DeFi金融平台
  16. 【边缘注意:深度多尺度特征】
  17. AST还原功能说明文档
  18. 个人训练赛第二十场:对撞
  19. ChatGpt 能取代人类吗?
  20. C语言--入门程序hello world

热门文章

  1. mysqlbinlog工具_mysqlbinlog命令详解 Part 5 通过位置和时间查看日志
  2. SpringBoot中的定时任务的同步与异步
  3. nohup命令导致nohup.out文件过大处理办法
  4. Android Studio 3.1无法导入模块的解决办法
  5. Android开发笔记(六十六)自定义对话框
  6. 操作指针的条件和多级指针
  7. 突然发现一个很好用Golang的json库
  8. SI和DI寄存器(0703)
  9. Android学习系列--App调试的几个命令实践
  10. Visual Studio的工程结构解析