Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 506 Accepted Submission(s): 161
3
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
1
Case #1: 32
Case #2: 16
Case #3: 1
/** 题意:给一个树,现在要求一个树的叶子结点之间的数十连续的,并且一个树的所有的 子数节点的数也是连续的 做法:搜索 如果当前节点头n个节点,如果没有非叶子的节点那么它的可能是n! 否则 如果存在一个非叶子节点 那么就是2*(n-1)! 一段区间的开始和结束 如果存在两个非叶子节点 那么就是2*(n-2)! 如果非叶子节点大于2 那么该树没有解 **/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cmath> #include <algorithm> #include <string.h> #include <stdio.h> #include <vector> using namespace std; #define maxn 100000 + 10 const int mod = 1e9 + 7; vector<int>G[maxn]; long long res = 0; int vis[maxn]; bool flag = true; void dfs(int u) { vis[u] = 1; int tt = G[u].size(); int cet = 0; for(int i = 0; i < tt; i++) { int v = G[u][i]; if(vis[v]) { continue; } if(G[v].size() == 1 && vis[v] == 0) { cet++; } else if(vis[v] == 0) { dfs(v); } } if(u != 1) { tt--; } if(tt - cet > 2) { flag = false; return; } if(tt - cet > 0) { res *= 2; res %= mod; } while(cet > 0) { res *= cet; res %= mod; cet--; } } int main() { int T; scanf("%d", &T); int Case = 1; while(T--) { int n; scanf("%d", &n); int u, v; memset(vis, 0, sizeof(vis)); for(int i = 0; i <= n; i++) { G[i].clear(); } for(int i = 0; i < n - 1; i++) { scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } res = 1; flag = true; dfs(1); if(n == 1) { res = 1; } else { res *= 2; } if(flag == false) { printf("Case #%d: 0\n", Case++); } else { printf("Case #%d: %lld\n", Case++, res % mod); } } return 0; }
原文:http://www.cnblogs.com/chenyang920/p/4722593.html