[hdu5379]Mahjong tree

一棵子树的每一个儿子相当于划分一个区间,同时这些区间一定要存在一个点连续(直接的儿子),因此每一棵树最多只有两个儿子存在子树,并且这两个儿子所分到的区间一定是该区间最左和最右两段,所以ans*=(son)!(没有儿子的点任意排列)*2(两棵子树可以选择最左和最右),注意根节点还有两种划分方式,但当n=1时没有

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 #define mod 1000000007
 5 struct ji{
 6     int nex,to;
 7 }edge[N<<1];
 8 int E,t,n,x,y,ans,fac[N],head[N];
 9 void add(int x,int y){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     head[x]=E++;
13 }
14 bool dfs(int k,int fa){
15     int s1=0,s2=0;
16     for(int i=head[k];i!=-1;i=edge[i].nex)
17         if (edge[i].to!=fa){
18             s1++;
19             s2+=dfs(edge[i].to,k);
20         }
21     if (s2>2)ans=0;
22     if (s2)ans=ans*2%mod;
23     ans=1LL*ans*fac[s1-s2]%mod;
24     return (s1>0);
25 }
26 int main(){
27     scanf("%d",&t);
28     fac[0]=1;
29     for(int i=1;i<N-4;i++)fac[i]=1LL*fac[i-1]*i%mod;
30     for(int ii=1;ii<=t;ii++){
31         scanf("%d",&n);
32         ans=2;
33         E=0;
34         for(int i=1;i<=n;i++)head[i]=-1;
35         for(int i=1;i<n;i++){
36             scanf("%d%d",&x,&y);
37             add(x,y);
38             add(y,x);
39         }
40         dfs(1,0);
41         if (n==1)ans=1;
42         printf("Case #%d: %d\n",ii,ans);
43     }
44 }
View Code

猜你喜欢

转载自www.cnblogs.com/PYWBKTDA/p/11286362.html