zoukankan      html  css  js  c++  java
  • HDU 4013 Distinct Subtrees(树的最小表示)

    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 = 22 ;
    int n , g[N][N] , a[N] , b[N] , st , ans ;
    
    struct trie {
        int date;
        struct trie* son[2];
    }*root;
    
    void init() {
        ans = 0 ;
        memset( g , 0 , sizeof g ) ;
        root = new trie ;
        root -> date = 0 ;
        root -> son[0] = NULL;
        root -> son[1] = NULL;
    }
    int insert( string s , struct trie *p ) {
        struct trie *rot = p ;
        for( int i = 0 ; i < s.size() ; ++i ) {
            if( rot -> son[ s[i] - '0'] == NULL ) {
                trie *t = new trie ;
                t -> date = 0 ;
                t -> son[0] = NULL ;
                t -> son[1] = NULL ;
                rot -> son[ s[i] - '0' ] = t ;
            }
            rot = rot -> son[ s[i] - '0' ] ;
        }
        if( rot -> date == 1 ) return 0 ;
        rot -> date = 1 ;
        return 1 ;
    }
    
    string dfs1( int u , int p ) {
        string vs = "0";
        vector<string>q;
        for( int i = 0 ; i < n ; ++i )
            if( (st&(1<<i)) && g[u][i] && i != p )
                q.push_back(dfs1(i,u));
        sort( q.begin() , q.end() );
        for( int i = 0 ; i < q.size() ; ++i ) vs += q[i] ;
        vs += "1";
        return vs ;
    }
    
    int solve() {
        int f = 0 , t ;
        string s ;
        for( int i = 0 ; i < n ; ++i ) if( st&(1<<i) ){
            s = dfs1( i , -1 );
            t = insert( s , root );
            if( (!t)&& (!f) ) return 0 ;
            f = 1 ;
        }
        return 1 ;
    }
    
    int main() {
        string s ;
        ios::sync_with_stdio(0);
        int _ , cas = 1 ; cin >> _ ;
        while( _-- ) {
            cin >> n ;
            init() ;
            for( int i = 1; i < n ; ++i ) {
                int u , v ; cin >> u >> v ;
                u-- , v-- ;
                g[u][v] = g[v][u] = 1 ;
            }
            for( int i = 1 ; i < (1<<n) ; ++i ) {
                st = i ;
                ans += solve();
            }
            cout << "Case #"<< cas++ << ": " << ans << endl ;
        }
        return 0 ;
    }
    View Code
  • 相关阅读:
    (转)ios限制控制器旋转
    iOS NSMutableURLRequest 上传图片
    iOS中UIWebView使用JS交互
    Cocoa pods的安装和使用
    NSThread/NSOperation/GCD 三种多线程技术
    动画效果-基础动画设置(改变大小,改变透明度,翻转,旋转,复原)
    动画效果一风火轮加载效果/动态图展示
    Swift代理和传值
    Swift基础(类,结构体,函数)
    IOS面试问题总结
  • 原文地址:https://www.cnblogs.com/hlmark/p/4389523.html
Copyright © 2011-2022 走看看