As we all know, Matt is an outstanding contestant in ACM-ICPC. Graph problems are his favorite.

Once, he came up with a simple algorithm for finding the maximal independent set in trees by mistake.

A tree is a connected undirected graph without cycles, and an independent set is subset of the vertex set which contains no adjacent vertex pairs.

Suppose that the tree contains N vertices, conveniently numbered by 1,2, . . . , N. First, Matt picks a permutation p1, p2, . . . , pN of {1, 2, 3, . . . , N } randomly and uniformly.

After picking the permutation, Matt does the following procedure.

1.Set S = ∅.
2.Consider the vertex p1, p2, . . . , pN accordingly. For vertex pi, if and only if there is no vertex in S which is adjacent to pi, add vertex pi into S.
3.Output the set S.

Clearly the above algorithm does not always output the maximal independent set. Matt would like to know the expected size of set S instead.

 

Input

The first line contains only one integer T , which indicates the number of test cases.

For each test case, the first line contains an integer N (1 ≤ N ≤ 200), indicating the number of vertices in the graph.

Each of the following N - 1 lines contains two integers u, v (1 ≤ u, v ≤ N ) indicating an edge between u and v. You may assume that all the vertices are connected.

 

Output

For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y is the answer. To avoid rounding error, the answer you should output is:

(the expected size of independent set) × N! mod (109 + 7)

 

Sample Input

2
4
1 2
1 3
1 4
3
1 2
2 3

Sample Output

Case #1: 60
Case #2: 10

Hint

In the first sample, there are 4 vertices, so there are 4! permutations Matt may get. Suppose the permutation Matt gets is 1 2 3 4. He will add vertex 1 into the independent set. Suppose the permutation Matt gets is 2 1 3 4. He will add vertex 2, vertex 3 and vertex 4 into the independent set. It is obvious that if the first element in the permutation is not vertex 1, he will get an independent set whose size is 3. Otherwise, he well get an independent set whose size is 1. Since there are 18 permutations whose first element is not vertex 1, the answer in the first sample is (3 × 18 + 1 × 6) mod (10^9 + 7) = 60.
  好题好题,我有幸成为了HDU第12名A穿此题的人。
  这道题就是对任意1~n的排列跑题中所给的程序,得到的集合S,求sigma(|S|)。
  考虑dp,dp[x][i]表示x在当前以它为根的子树中的所有1~sz[x]的排列中位置在i,并且x被选入集合的排列数。
  枚举根节点,发现不同子树间互不影响,只有父亲与儿子之间才会有影响,现在就是dp的形式就是两组排列,相互安插,用组合数搞一搞。
  枚举to[i]这棵子树的1~sz[to[i]]的集合中前a个插在x前面,后面的sz[to[i]]-a个在x后面,乘上dp[x][i],再乘上选位置的方案,选位置的话,x个数插到y个数中,方案数是C(x+y,x)
  时刻要记得取模……         貌似我的题解是此题网络上的第一篇BLOG,好开心……
 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=,Mod=(int)1e9+;
int cnt,fir[N],to[N*],nxt[N*];
void addedge(int a,int b){
nxt[++cnt]=fir[a];to[fir[a]=cnt]=b;
nxt[++cnt]=fir[b];to[fir[b]=cnt]=a;
}
typedef long long LL;
#define clr(x) memset(x,0,sizeof(x))
LL ans,dp[N][N],tmp[N],sum[N],fac[N],c[N][N];
LL Inv(LL x){return x==?:(Mod-Mod/x)*Inv(Mod%x)%Mod;}
void Prepare(){
fac[]=;
for(int i=;i<N;i++)
fac[i]=fac[i-]*i%Mod;
for(int i=;i<N;i++)for(int j=;j<=i;j++)
c[i][j]=fac[i]*Inv(fac[j]*fac[i-j]%Mod)%Mod;
} int fa[N],sz[N];
void Update(int x,int y){
clr(sum);clr(tmp);
for(int i=;i<=sz[y];i++)
sum[i]=(sum[i-]+dp[y][i])%Mod; for(int i=;i<=sz[x];i++)
for(int j=;j<=sz[y];j++){
LL a=dp[x][i]*(((fac[sz[y]]-sum[j])%Mod+Mod)%Mod)%Mod;
LL b=c[i+j-][j]*c[sz[x]+sz[y]-i-j][sz[y]-j]%Mod;
(tmp[i+j]+=a*b%Mod)%=Mod;
}
sz[x]+=sz[y];
for(int i=;i<=sz[x];i++)
dp[x][i]=tmp[i];
} void DP(int x,int f){
if(fa[x]==f)return;
clr(dp[x]);sz[x]=;
fa[x]=f;dp[x][]=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=f){
DP(to[i],x);
Update(x,to[i]);
}
} int st[N],top;
void DFS(int x,int f){
st[++top]=x;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=f)DFS(to[i],x);
}
int T,cas,n,a,b;
void Init(){
clr(fir);clr(fa);
top=ans=cnt=;
} int main(){
Prepare();
scanf("%d",&T);
while(T--){
Init();
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
}
DFS(,);
for(int i=;i<=n;i++){
DP(st[i],-);
for(int j=;j<=n;j++)
(ans+=dp[st[i]][j])%=Mod;
}
printf("Case #%d: %lld\n",++cas,ans);
}
return ;
}
 

动态规划(DP计数):HDU 5121 Just A Mistake的更多相关文章

  1. HDU 5121 Just A Mistake

    Just A Mistake Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) ...

  2. 动态规划(DP计数):HDU 5116 Everlasting L

    Matt loves letter L.A point set P is (a, b)-L if and only if there exists x, y satisfying:P = {(x, y ...

  3. HDU 4055 The King’s Ups and Downs(DP计数)

    题意: 国王的士兵有n个,每个人的身高都不同,国王要将他们排列,必须一高一矮间隔进行,即其中的一个人必须同时高于(或低于)左边和右边.问可能的排列数.例子有1千个,但是最多只算到20个士兵,并且20个 ...

  4. HDU 4055 Number String(DP计数)

    题意: 给你一个含n个字符的字符串,字符为'D'时表示小于号,字符为“I”时表示大于号,字符为“?”时表示大小于都可以.比如排列 {3, 1, 2, 7, 4, 6, 5} 表示为字符串 DIIDID ...

  5. 动态规划dp

    一.概念:动态规划dp:是一种分阶段求解决策问题的数学思想. 总结起来就一句话:大事化小,小事化了 二.例子 1.走台阶问题 F(10):10级台阶的走法数量 所以:F(10)=F(9)+F(8) F ...

  6. 【POJ1952】逢低吸纳 dp+计数

    题目大意:给定一个有 N 个数的序列,求其最长下降子序列的长度,并求出有多少种不同的最长下降子序列.(子序列各项数值相同视为同一种) update at 2019.4.3 题解:求最长下降子序列本身并 ...

  7. 算法-动态规划DP小记

    算法-动态规划DP小记 动态规划算法是一种比较灵活的算法,针对具体的问题要具体分析,其宗旨就是要找出要解决问题的状态,然后逆向转化为求解子问题,最终回到已知的初始态,然后再顺序累计各个子问题的解从而得 ...

  8. Tetrahedron(Codeforces Round #113 (Div. 2) + 打表找规律 + dp计数)

    题目链接: https://codeforces.com/contest/166/problem/E 题目: 题意: 给你一个三菱锥,初始时你在D点,然后你每次可以往相邻的顶点移动,问你第n步回到D点 ...

  9. 动态规划(DP计数):HDU 5117 Fluorescent

    Matt, a famous adventurer who once defeated a pack of dire wolves alone, found a lost court. Matt fi ...

随机推荐

  1. 常用JS正则表达式收集

    1.去掉字符串前后空格,不会修改原有字符串,返回新串.str.replace(/(^\s*)|(\s*$)/g,'');

  2. 转:HashMap的工作原理,及笔记

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...

  3. Spring学习之代理

    Spring的核心就是IOC和AOP IOC就是控制反转:   就是用配置文件的方式给javabean 赋值. 正常的在程序里;用new 的方式创建一个对象的时候,他就固定了值, 如果是注入的方式的话 ...

  4. SQLite学习第02天:数据类型

    参考资料:http://www.w3cschool.cc/sqlite/sqlite-data-types.html 在SQLite中,数据类型的概念看起来很模糊,刚开始接触感觉跟C语言提供的数据类型 ...

  5. JVM内存管理基本概念

    java中是否存在内存泄露? 在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连:其次,这些对象是无用的,即程序以后不会 ...

  6. Windows API 常量定义

    Windows 常量定义在winuser.h中可以找到,如果了安装了visual studio 2010,winuser.h所在目录为C:\Program Files (x86)\Microsoft ...

  7. skip index scan

    官网对skip index scan的解释: Index skip scans improve index scans by nonprefix columns since it is often f ...

  8. ARM中的PC和AXD的PC

    R15 (PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令.一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC 总是指向第三条指令 ...

  9. EntityFramework动态组合多排序字段

    前言:在使用EF当中,肯定会遇到动态查询的需求,建立一个公共调用的动态组合表达式查询也是必不可少的,以下是建立动态组合多排序字段做个记录,供以后调用 1.建立一个结构,用于多个排序字段组合,这个结构体 ...

  10. shell脚本学习积累笔记(第一篇)

    (1)首先,今天在执行shell脚本./test.sh时抛出“/bin/sh^M: bad interpreter: No such file or directory”的异常,百度后,才知道这是由于 ...