在一棵树上给所有点标号,要求任意一个子树里的点编号连续,每一个点的儿子编号连续。 那么,一个点的非叶子儿子应该是连续的,即一个点的非叶子儿子最多只有两个。 对于每一个点,我们把它的叶子儿子的个数记作S,所有儿子的方案数积为T。当非叶子儿子节点个数小于2的时候,方案数为2T*(S!). 当非叶子儿子节点数等于2的时候,这个点为根的子树合法方案数位T*(S!). 这样dfs一遍即可以处理整棵树的方案数。
2 9 2 1 3 1 4 3 5 3 6 2 7 4 8 7 9 3 8 2 1 3 1 4 3 5 1 6 4 7 5 8 4
Case #1: 32 Case #2: 16
/* *********************************************** Author :CKboss Created Time :2015年08月12日 星期三 10时23分35秒 File Name :HDOJ5379.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; typedef long long int LL; const int maxn=100100; const LL mod=1e9+7; int n; LL jc[maxn]; int sons[maxn],s[maxn]; LL dp[maxn]; vector<int> G[maxn]; void JC() { jc[0]=1LL; for(LL i=1;i<maxn;i++) jc[i]=(jc[i-1]*i)%mod; } void init() { for(int i=1;i<=n;i++) { G[i].clear(); sons[i]=0; s[i]=0; dp[i]=0; } } void check_dfs(int u,int fa) { sons[u]=G[u].size(); if(u!=fa) sons[u]--; if(sons[u]==0) return ; LL ts=0; for(int i=0,sz=G[u].size();i<sz;i++) { int v=G[u][i]; if(v==fa) continue; check_dfs(v,u); if(sons[v]==0) ts++; } s[u]=sons[u]-ts; } void dfs(int u,int fa) { if(sons[u]==0) { dp[u]=1LL; return ; } LL T=1; for(int i=0,sz=G[u].size();i<sz;i++) { int v=G[u][i]; if(v==fa||v==0) continue; dfs(v,u); T=(T*dp[v])%mod; } if(s[u]==2) { dp[u]=T*jc[sons[u]-2]%mod; } else { dp[u]=2*T*jc[sons[u]-s[u]]%mod; } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); JC(); int cas=1,T_T; scanf("%d",&T_T); while(T_T--) { scanf("%d",&n); init(); for(int i=0,u,v;i<n-1;i++) { scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } check_dfs(1,1); bool fg=true; for(int i=1;i<=n&&fg;i++) if(s[i]>2) fg=false; if(fg==false) { printf("Case #%d: 0\n",cas++); continue; } dfs(1,1); //for(int i=1;i<=n;i++) printf("%d: dp:%lld sons: %d s: %d\n",i,dp[i],sons[i],s[i]); printf("Case #%d: %d\n",cas++,(int)dp[1]); } return 0; }