• Hdu 5379 Mahjong tree (dfs + 组合数)


    题目链接:

      Hdu 5379 Mahjong tree

    题目描述:

      给出一个有n个节点的树,以节点1为根节点。问在满足兄弟节点连续 以及 子树包含节点连续 的条件下,有多少种编号方案给树上的n个点编号?

    解题思路:

      对于一个节点来讲,非叶子儿子节点最多有两个才能满足要求,否则满足子树节点连续的话就无法满足兄弟节点连续。然后有dfs计算每棵子树的贡献值,每棵子树的子节点可以分为叶子节点X和非叶子节点Y,叶子节点可以分配到一组连续的编号,非叶子节点只能分配到兄弟节点中最大或者最小编号两种情况,叶子节点的贡献值为X!。然后dfs跑一下就ok咯。

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 #pragma comment (linker, "/STACK:1024000000,1024000000")
     7 using namespace std;
     8 
     9 const int maxn = 100005;
    10 const int mod = (1e9 + 7);
    11 typedef long long LL;
    12 struct node
    13 {
    14     int to, next;
    15 }edge[maxn*2];
    16 int head[2][maxn], vis[maxn], tot, flag;
    17 LL res;
    18 
    19 void Add (int from, int to)
    20 {
    21     edge[tot].to = to;
    22     edge[tot].next = head[0][from];
    23     head[0][from] = tot ++;
    24     head[1][from] ++;
    25 }
    26 
    27 void dfs (int u)
    28 {
    29     int k, cnt;
    30     k = cnt = 0;
    31     vis[u] = 1;
    32     for (int i=head[0][u]; i!=-1; i=edge[i].next)
    33     {
    34 
    35         int v = edge[i].to;
    36         if (vis[v])
    37             continue;
    38         if (!vis[v] && head[1][v]==1)
    39             cnt ++;
    40         else
    41             dfs (v);
    42         k ++;
    43     }
    44     if (k - cnt > 2)
    45     {
    46         res = 0;
    47         return;
    48     }
    49     if (k != cnt)
    50         res = (res * 2) % mod;
    51     while (cnt)
    52     {
    53         res = (res * cnt) % mod;
    54         cnt --;
    55     }
    56 }
    57 int main ()
    58 {
    59     int t, n, l = 0;
    60     scanf ("%d", &t);
    61 
    62     while (t --)
    63     {
    64         scanf ("%d", &n);
    65         memset (head[0], -1, sizeof(head[0]));
    66         memset (head[1], 0, sizeof(head[1]));
    67         memset (vis, 0, sizeof(vis));
    68         tot = flag = 0;
    69 
    70        for (int i=1; i<n; i++)
    71         {
    72             int u, v;
    73             scanf ("%d %d", &u, &v);
    74             Add (u, v);
    75             Add (v, u);
    76         }
    77         res = 2;
    78         dfs (1);
    79         printf ("Case #%d: %lld
    ", ++l, n==1?1:res);
    80     }
    81     return 0;
    82 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Bash的提示符
    小笨霖英语笔记本(5)
    什么是VLAN
    阅读笔记:双核心Opteron处理器
    小笨霖英语笔记本(4)
    搭乘CCNUMA快车
    得到tnsnames.ora文件的位置 zz
    关于64位Windows操作系统中的注册表 zz
    Temp.Misc
    HttpHandler HttpModule入门篇
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4723911.html
Copyright © 2020-2023  润新知