题意:给定一棵树
把1-n填到树的节点上,使得:
1:儿子节点上填的数字是连续的。
2:子树节点上填的数字是连续的。
把儿子节点分成两种,一种是叶子节点,一种是非叶子节点。
显然非叶子节点个数不能超过2个,不然就不存在这样的方案了。
然后分类讨论一下非叶子节点个数即可。
#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <map> #include <vector> using namespace std; template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) pt(x / 10); putchar(x % 10 + '0'); } typedef pair<int, int> pii; typedef long long ll; const int N = 100000+10; const int mod = 1e9 + 7; struct Edge { int to, nex; }edge[N << 1]; int head[N], edgenum; void add(int u, int v) { Edge E = { v, head[u] }; edge[edgenum] = E; head[u] = edgenum++; } int n; int siz[N], A[N]; int ans; void mul(int x) { ans = (ll)ans*x%mod; } void dfs(int u, int fa) { siz[u] = 1; int num = 0, num2 = 0; for (int i = head[u]; ~i; i = edge[i].nex) { int v = edge[i].to; if (v == fa)continue; dfs(v, u); siz[u] += siz[v]; if (siz[v] == 1)num2++; else num++; } if (siz[u] == 1)return; if (num > 2)ans = 0; else if (num == 0) { mul(A[num2]); } else { mul(2); mul(A[num2]); } } int main() { A[0] = 1; for (int i = 1; i < N; i++)A[i] = (ll)A[i - 1] * i%mod; int T, Cas = 1; rd(T); while (T--) { rd(n); for (int i = 1; i <= n; i++)head[i] = -1;edgenum = 0; for (int i = 1, u, v; i < n; i++) { rd(u); rd(v); add(u, v); add(v, u); } ans = 1; dfs(1, 1); if (n != 1)mul(2); printf("Case #%d: ", Cas++); pt(ans); puts(""); } return 0; } /* 99 7 1 2 1 5 2 3 2 4 5 6 5 7 10 1 2 1 3 1 4 2 5 2 6 3 7 3 8 4 9 4 10 */
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-10 16:10:20