树形dp,每个节点最多有2个子节点为一棵节点数大于1的子树的根节点,而且要么后代的节点值都大于,要么都小于本身(所以tson不为0是,要乘2)。对于K个单一节点的子节点,种类数即为全排K!。当一个节点没有兄弟节点时,以这个节点为根结点的子树,根可以选择最大或者最小。
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100005;
const int mod = 1e9 + 7;
int N, son[maxn], tson[maxn], out[maxn], fac[maxn];
vector<int> G[maxn];
int dfs (int u, int f) {
son[u] = tson[u] = 0;
ll ret = out[u] = 1;
//printf("%d %I64d\n", u, ret);
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == f)
continue;
ret = ret * dfs(v, u) % mod;
son[u]++;
out[u] += out[v];
if (out[v] > 1)
tson[u]++;
}
ret = ret * fac[son[u] - tson[u]] % mod;
if (tson[u])
ret = ret * 2 % mod;
//printf("%d:%d %d %I64d\n", u, son[u], tson[u], ret);
if (tson[u] > 2)
ret = 0;
return ret;
}
void init () {
scanf("%d", &N);
for (int i = 1; i <= N; i++)
G[i].clear();
/*
memset(son, 0, sizeof(son));
memset(out, 0, sizeof(out));
memset(tson, 0, sizeof(tson));
*/
int u, v;
for (int i = 1; i < N; i++) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
}
int main () {
fac[0] = fac[1] = 1;
for (int i = 2; i <= 100000; i++)
fac[i] = 1LL * i * fac[i-1] % mod;
int cas;
scanf("%d", &cas);
for (int kcas = 1; kcas <= cas; kcas++) {
init ();
if (N == 1)
printf("Case #%d: 1\n", kcas);
else
printf("Case #%d: %I64d\n", kcas, 2LL * dfs(1, 0) % mod);
}
return 0;
}