• ZOJ 3602 树的同构


    题意:

    给出 n m 代表第一棵树有 n 个节点 第二棵树有 m 个节点

    然后接下来 n+m 行给出 a b 表示第 i 个节点的左孩子是 a 右孩子是 b

    问这两棵树中有多少棵子树是相同的..

    eg:

    View Code
    Sample Input
    
    2
    2 2
    -1 2
    -1 -1
    2 -1
    -1 -1
    5 5
    2 3
    4 5
    -1 -1
    -1 -1
    -1 -1
    2 3
    4 5
    -1 -1
    -1 -1
    -1 -1
    Sample Output
    
    1
    11
    Hint
    
    The two trees in the first sample look like this.

     

     

    思路:

    根据输入的信息建树..

     

    用 deg 数组记录这棵树的第 i 个节点有多少棵子树..

    用 hash[ t ][ i ] 表示第 t 棵树中第 i 个节点的 hash 值是多少..

    用 sum[ t ][ i ] 表示第 t 棵树种 hash 值是 i 的子树有多少棵..

    先处理第一棵树..

    从叶子节点开始处理.. 把是叶子节点的都加入队列..

    然后根据 map<pair<L, R>, p>.. 把这棵树的每个节点都映射成唯一表示的值..

     

    第一次接触 hash.. 感觉hash就是根据一定方法找到一个 key 值唯一标识对应给出的信息..然后通过 key 值找给出的数据..

    这里 hash 值的处理方法是定义一个结构体 pair<int, int> 表示该节点的左右孩子

    然后用 map<pair<L, R>, p> 映射来唯一表示这个节点 p..对叶子节点统一 映射为 pair<-1, -1>

    根据左右孩子的特征值再唯一确定节点 p 的 hash 值 mp[p] = mp.size()+1..

    对应sum[ t ][p节点对应hash值] ++ 来表示有过这个状态的子树..

    处理第二棵树的时候..

    用同样的方法求出特征值以及对应的hash值..

    然后看在第一棵树中有没有这种状态的树..

    用 ans += sum[ t ][ mp[p] ];求出要求的解..

    其中每处理完一个节点..就让它的根节点的对应deg[ ]--;当deg[父节点]退化为叶子节点..就加入队列..

    Tips:

    ※ deg[ 0 ] 是头头节点..为了防止被加入队列..一开始应该初始化为 3

    ※ 因为 n 和 m 很大..所以答案的范围应该定义为 长整型

    Code:

    View Code
     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <map>
     5 #include <queue>
     6 using namespace std;
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 const int maxn = 100010;
     9 
    10 struct Node
    11 {
    12     int ff;
    13     int ls;
    14     int rs;
    15 }node[2][maxn];
    16 
    17 int sum[2][maxn], hash[2][maxn], deg[maxn], n[2];
    18 map<pair<int, int>, int> mp;
    19 long long ans;///!!!
    20 
    21 void bfs(int t)
    22 {
    23     queue<int> Q;
    24     int tmp, L, R;
    25     int i, j, k;
    26     deg[0] = 3;
    27 
    28     for(i = 1; i <= n[t]; ++i)
    29     {
    30         deg[i] = (node[t][i].ls != -1) + (node[t][i].rs != -1);
    31         if(deg[i] == 0)
    32         {
    33             Q.push(i);
    34             hash[t][i] = 0;
    35         }
    36     }
    37 
    38     while(!Q.empty())
    39     {
    40         tmp = Q.front();
    41         Q.pop();
    42 
    43         L = -1;
    44         if(node[t][tmp].ls != -1)
    45             L = hash[t][node[t][tmp].ls]; 
    46         R = -1;
    47         if(node[t][tmp].rs != -1)
    48             R = hash[t][node[t][tmp].rs];
    49 
    50         pair<int, int> p = make_pair(L, R);
    51         if(mp[p] == 0) mp[p] = mp.size()+1;
    52         sum[t][mp[p]]++;
    53         hash[t][tmp] = mp[p];
    54 
    55         if(t == 1) ans += sum[0][mp[p]];
    56 
    57         deg[node[t][tmp].ff]--;
    58         if(deg[node[t][tmp].ff] == 0) {
    59             Q.push(node[t][tmp].ff);
    60         }
    61     }
    62 }
    63 
    64 
    65 int main()
    66 {
    67     int i, j, k;
    68     int T, nn, mm;
    69     while(scanf("%d", &T) != EOF)
    70     while(T--)
    71     {
    72 
    73         mp.clear();
    74         ans = 0;
    75         node[0][1].ff = node[1][1].ff = 0;
    76         memset(sum, 0, sizeof(sum));
    77 
    78         scanf("%d %d", &nn, &mm);
    79         n[0] = nn, n[1] = mm;
    80         for(i = 0; i < 2; ++i)
    81             for(j = 1; j <= n[i]; ++j)
    82             {
    83                 scanf("%d %d", &node[i][j].ls, &node[i][j].rs);
    84                 if(node[i][j].ls != -1) node[i][node[i][j].ls].ff = j;
    85                 if(node[i][j].rs != -1) node[i][node[i][j].rs].ff = j;
    86             }
    87 
    88         bfs(0), bfs(1);
    89 
    90         printf("%lld\n", ans);
    91     }
    92     return 0;
    93 }

     

  • 相关阅读:
    视频遮挡问题
    calc兼容性
    javascript变量声明提升
    jquery插件
    prop和attr在 jquery的
    onclick防止冒泡和json对象放入
    git 入门
    去掉ie滚动条兼容性
    单页面应用程序(SPA)
    swiper轮播图插件
  • 原文地址:https://www.cnblogs.com/Griselda/p/2680515.html
Copyright © 2020-2023  润新知