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
题意:一颗n个节点n-1条边的树,现在要给每个节点标号(1~n),要求:(1)每一层的兄弟节点的标号要是连续的(2)每一颗子树的所有节点标号是连续的。问有多少种标号方案。
思路:对于每一层顶多只能存在2个非叶子节点,否则无解;对于每一层有x个叶子节点,y个非叶子节点,那么ans=(ans * x!)%mod,另外如果y!=0,还得ans=2*ans%mod。
代码:
#include <iostream> #include <functional> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define pi acos(-1.0) #define eps 1e-6 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define FRE(i,a,b) for(i = a; i <= b; i++) #define FREE(i,a,b) for(i = a; i >= b; i--) #define FRL(i,a,b) for(i = a; i < b; i++) #define FRLL(i,a,b) for(i = a; i > b; i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define DBG pf("Hi\n") typedef long long ll; using namespace std; #define INF 0x3f3f3f3f #define mod 1000000007 const int maxn = 1005; const int MAXN = 100001; const int MAXM = 200002; const int N = 1005; struct Edge { int u,v,next; }edge[MAXM]; int tot,head[MAXN],n; ll fn[MAXN],ans; bool flag; void INIT() { fn[0]=1; for (int i=1;i<=100000;i++) fn[i]=(fn[i-1]*(ll)i)%mod; } void init() { tot=0;flag=true;ans=1; memset(head,-1,sizeof(head)); } void addedge(int u,int v) { edge[tot].u=u; edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++; } ll dfs(int u,int pre) { if (!flag) return 0; ll s=1,all=0,ss=0; for (int i=head[u];~i;i=edge[i].next) { int v=edge[i].v; if (v==pre) continue; ll x=dfs(v,u); s+=x; if (x==1) all++; else if (x>1) ss++; } if (ss>2) flag=false; else{ ans=(ans*fn[all])%mod; if (ss!=0) ans=((ll)2*ans)%mod; } return s; } int main() { #ifndef ONLINE_JUDGE freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin); #endif int i,j,t,u,v,cas=0; INIT(); scanf("%d",&t); while (t--) { scanf("%d",&n); init(); for (i=0;i<n-1;i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs(1,-1); if (n>1) ans=((ll)2*ans)%mod; if (!flag) ans=0; printf("Case #%d: %lld\n",++cas,ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014422052/article/details/47427311