Hdu 4013 Distinct Subtrees (状态压缩枚举+树的最小表示)
2013-07-17 22:15
316 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4013
题意:一棵由无向边构成的树,求出它的不同的子树的数目。
思路:枚举每个点集,DFS求最小表示。对于某一种情况,若有一次得到的表示以前没有,答案加1。
代码中有一大段被注释掉的部分,那是我最开始的想法,会出现同一棵子树因树根不同而重复记录的情况 。
如果一个点集构成森林,由于遍历了所有组成,所以它的每一棵树都会被遍历到。
本题时间限制5000MS,我的代码跑了4312MS……
摘录一下其他人的写法:
hdu 4013 子树同构问题 - YoMean!的日志 - 网易博客
http://yomean.blog.163.com/blog/static/18942022520120200323829/
HDU 4013 Distinct Subtrees(树的最小表示)_年轻_百度空间
http://hi.baidu.com/tomtongjiantao/item/0c04eb45c46b8c2a11ee1e48
HDU 4013 图论 树的最小表示 - 源码力量 - 博客频道 - CSDN.NET
http://blog.csdn.net/codeforces_sphinx/article/details/7210989
题意:一棵由无向边构成的树,求出它的不同的子树的数目。
思路:枚举每个点集,DFS求最小表示。对于某一种情况,若有一次得到的表示以前没有,答案加1。
代码中有一大段被注释掉的部分,那是我最开始的想法,会出现同一棵子树因树根不同而重复记录的情况 。
如果一个点集构成森林,由于遍历了所有组成,所以它的每一棵树都会被遍历到。
本题时间限制5000MS,我的代码跑了4312MS……
#pragma warning(disable:4786) #include <set> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n,map[15][15]; bool visit[15]; set<string> s; string DFS (int u,int pre) { vector<string> v; for (int i=0;i<n;i++) if (map[u][i] && i!=pre && visit[i]) v.push_back('0'+DFS(i,u)); string r; sort (v.begin(),v.end()); for (int k=0;k<v.size();k++) r+=v[k]; return r+'1'; } /*错误的处理方式 int Deal () { int j; for (int i=0;i<(1<<n);i++) //枚举点集 { memset(visit,false,sizeof(visit)); for (j=0;j<n;j++) if (i&(1<<j)) visit[j]=1; for (j=0;j<n;j++) if (visit[j]) s.insert(DFS(j,-1)); } return s.size(); }*/ int Deal () { int j,ans=0; for (int i=0;i<(1<<n);i++) //枚举点集 { memset(visit,false,sizeof(visit)); for (j=0;j<n;j++) if (i&(1<<j)) visit[j]=true; int flag=0; for (j=0;j<n;j++) if (visit[j]) { string str=DFS(j,-1); if (s.find(str)==s.end()) //见题解 flag=1,s.insert(str); } ans+=flag; } return ans; } int main() { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif int T; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { s.clear(); scanf("%d",&n); memset(map,0,sizeof(map)); for (int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); map[u-1][v-1]=map[v-1][u-1]=1; } printf("Case #%d: %d\n",Cas,Deal()); } return 0; }
摘录一下其他人的写法:
hdu 4013 子树同构问题 - YoMean!的日志 - 网易博客
http://yomean.blog.163.com/blog/static/18942022520120200323829/
HDU 4013 Distinct Subtrees(树的最小表示)_年轻_百度空间
http://hi.baidu.com/tomtongjiantao/item/0c04eb45c46b8c2a11ee1e48
HDU 4013 图论 树的最小表示 - 源码力量 - 博客频道 - CSDN.NET
http://blog.csdn.net/codeforces_sphinx/article/details/7210989
相关文章推荐
- HDU 4013 Distinct Subtrees(树的最小表示)
- hdu 2489 状态压缩 + 最小生成树
- HDU 3220 Alice’s Cube 按位压缩表示状态+BFS
- hdu 1565 方格取数(1) (最小割/状态压缩+DP)
- HDU 4013 Distinct Subtrees(树同构)
- hdu 2489 Minimal Ratio Tree 最小生成树+状态压缩
- HDU 4013 图论 树的最小表示
- hdu 2489(状态压缩+最小生成树)
- hdu 2489 最小生成树状态压缩枚举
- HDU 1429 胜利大逃亡(续)(状态压缩表示,BFS)
- 文章标题 HDU 2489 : Minimal Ratio Tree (最小生成树+状态压缩二进制思想)
- hdu 4529 状态压缩DP
- hdu 5025 Saving Tang Monk(bfs+状态压缩)
- hdu 2609 How many(最小表示法模板+set判重)
- HDU 3374 KMP +字符串最小表示
- hdu 5892 沈阳网络赛 二维树状数组+状态压缩
- hdu 1565 方格取数(1) dp+状态压缩
- hdu 3920 Clear All of Them I (状态压缩DP)
- HDU - 2609 How many(最小表示法)
- HDU Victor and World (最短路+状态压缩)