Distinct Subtrees

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 391    Accepted Submission(s): 190

Problem Description
Given
an unrooted tree with n nodes, the subtree is defined as a connected
component of the given tree. Two subtrees are considered the same if
there exists a map from nodes of one tree to another so that the edges
of both trees are corresponding the same pair of nodes after mapping.
  Your task is to find out how many distinct subtrees for a given unrooted tree.
 
Input
The input consists of multiple test cases. The first line of input contains an integer denoting the number of test cases.
  For each test case, the first line contains one integer n denoting the number of nodes of the given tree. (1 <= n <= 15)
  Then n-1 lines follow, each line contains two integers denoting an edge of the tree (x, y).
 
Output
For each test case, output the number of distinct subtrees for the given tree.
 
Sample Input
2
3
1 2
1 3
9
9 4
4 3
1 3
7 4
1 6
5 7
2 4
6 8
 
Sample Output
Case #1: 3
Case #2: 21
 
 
问一棵树有多少棵结构不同的子树。
做法是将它dfs形式最小表示后,插入trie中
 
#include<bits/stdc++.h>
using namespace std ;
const int N = ;
int n , g[N][N] , a[N] , b[N] , st , ans ; struct trie {
int date;
struct trie* son[];
}*root; void init() {
ans = ;
memset( g , , sizeof g ) ;
root = new trie ;
root -> date = ;
root -> son[] = NULL;
root -> son[] = NULL;
}
int insert( string s , struct trie *p ) {
struct trie *rot = p ;
for( int i = ; i < s.size() ; ++i ) {
if( rot -> son[ s[i] - ''] == NULL ) {
trie *t = new trie ;
t -> date = ;
t -> son[] = NULL ;
t -> son[] = NULL ;
rot -> son[ s[i] - '' ] = t ;
}
rot = rot -> son[ s[i] - '' ] ;
}
if( rot -> date == ) return ;
rot -> date = ;
return ;
} string dfs1( int u , int p ) {
string vs = "";
vector<string>q;
for( int i = ; i < n ; ++i )
if( (st&(<<i)) && g[u][i] && i != p )
q.push_back(dfs1(i,u));
sort( q.begin() , q.end() );
for( int i = ; i < q.size() ; ++i ) vs += q[i] ;
vs += "";
return vs ;
} int solve() {
int f = , t ;
string s ;
for( int i = ; i < n ; ++i ) if( st&(<<i) ){
s = dfs1( i , - );
t = insert( s , root );
if( (!t)&& (!f) ) return ;
f = ;
}
return ;
} int main() {
string s ;
ios::sync_with_stdio();
int _ , cas = ; cin >> _ ;
while( _-- ) {
cin >> n ;
init() ;
for( int i = ; i < n ; ++i ) {
int u , v ; cin >> u >> v ;
u-- , v-- ;
g[u][v] = g[v][u] = ;
}
for( int i = ; i < (<<n) ; ++i ) {
st = i ;
ans += solve();
}
cout << "Case #"<< cas++ << ": " << ans << endl ;
}
return ;
}

HDU 4013 Distinct Subtrees(树的最小表示)的更多相关文章

  1. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  2. HDU 1954 Subway tree systems (树的最小表示法)

    题意:用一个字符串表示树,0代表向下走,1代表往回走,求两棵树是否同构. 分析:同构的树经过最小表示会转化成两个相等的串. 方法:递归寻找每一棵子树,将根节点相同的子树的字符串按字典序排列,递归回去即 ...

  3. hdu 6301 Distinct Values (思维+set)

    hdu 6301 Distinct Values 题目传送门 题意: 给你m个区间,让你求出一个长度为n的区间且满足在这些区间的数不重复, 并且要求字典序最小 思路: 如果我们已经求出这个序列了,你会 ...

  4. POJ 1635 树的最小表示法/HASH

    题目链接:http://poj.org/problem?id=1635 题意:给定两个由01组成的串,0代表远离根,1代表接近根.相当于每个串对应一个有根的树.然后让你判断2个串构成的树是否是同构的. ...

  5. HDU 5224 Tom and paper(最小周长)

    HDU 5224 Tom and paper(最小周长) Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d &a ...

  6. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  7. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  9. PAT甲题题解-1106. Lowest Price in Supply Chain (25)-(dfs计算树的最小层数)

    统计树的最小层数以及位于该层数上的叶子节点个数即可. 代码里建树我用了邻接链表的存储方式——链式前向星,不了解的可以参考,非常好用: http://www.cnblogs.com/chenxiwenr ...

随机推荐

  1. linux运维、架构之路-git版本管理

    一.常见版本管理系统 1.SVN     集中式的版本控制系统,只有一个中央数据仓库,如果中央数据仓库挂了或者不能访问,所有的使用者无法使用svn,无法进行提交或者备份文件 2.Git      分布 ...

  2. 如何生成各种mif文件,绝对经典!!!

    mif文件生成模板,只需要5步,很简单!!!!! 先说明如何操作,1-2-3-4-5步,后面附上模板!!! 下面以汉字去模演示过程: 1.取模软件设置:注意这里是设置的输出数据的格式!!!!!!!!! ...

  3. Vue在移动端App中使用的问题总结

    1.客户端中弹出键盘使得fixed布局错乱 Vue 在移动端中使用,当弹出键盘时,fixed 布局的元素可能会被键盘顶起. 例子图示及解决方法参考:https://blog.csdn.net/qq_3 ...

  4. luogu【P1024 一元三次方程求解】题解

    题目描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差 ...

  5. JavaScript实现Tab标签页切换的最简便方式

    转载请注明出处:http://www.cnblogs.com/-867259206/p/5664896.html 先说一下最土的一种方法: Html: <div class="tab- ...

  6. SQL ORDER BY 两个列

    ORDER BY  后可加2个字段,用英文逗号隔开. f1用升序, f2降序,sql该这样写 ORDER BY  f1, f2  DESC 也可以这样写,更清楚: ORDER BY  f1 ASC, ...

  7. Linux驱动开发6——DDR内存分配

    1.kmalloc和kfree #include <linux/slab.h> void *kmalloc(size_t size, int flags); flag: GFP_ATOMI ...

  8. 使用 Python 实现多进程

    w 使用 Python 实现多进程https://www.ibm.com/developerworks/cn/aix/library/au-multiprocessing/

  9. 圆角Panel

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostic ...

  10. WinForm实现最小化右下角

    首先,要在窗体里面加入这么两个控件,左边的是托盘控件,右边的是菜单控件. 然后设置窗体的FormClosing事件: if (e.CloseReason == CloseReason.UserClos ...