题解:P13484 [GCJ 2008 EMEA SemiFinal] Rainbow Trees
闲话:希望明天 CSP 会出这种简单而有趣的数数题。
先简化问题:考虑如果只有相邻边不相同的限制,怎么求方案数。\
事实上是简单的,假设以
考虑距离为
初始的时候随便找一条边作为红边,假设红边已经确定颜色(
时间复杂度
#include <bits/stdc++.h>
using namespace std;
const int N = 505, M = N << 1, mod = 1e9 + 9;
int T, n, k, h[N], e[M], ne[M], idx;
int X, Y, deg[N];
inline void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
int A(int n, int m) {
long long res = 1; for (int i = n - m + 1; i <= n; i++) (res *= i) %= mod;
return res;
}
long long ans;
void dfs(int x, int y, int t, int a) {
(ans *= A(k - a, t - a)) %= mod;
if (deg[y] == 1) return;
for (int i = h[y]; ~i; i = ne[i]) {
int v = e[i]; if (v == x) continue;
dfs(y, v, deg[y] + deg[v] - 1, deg[y]);
}
}
void solve(int id) {
scanf("%d%d", &n, &k), ans = 1;
for (int i = 1; i <= n; i++) h[i] = -1, deg[i] = 0; idx = 0;
for (int i = 1, a, b; i < n; i++) scanf("%d%d", &a, &b), add(a, b), add(b, a), deg[a]++, deg[b]++;
for (int i = 1; i <= n; i++) if (deg[i] == 1) { X = i; break; }
for (int i = h[X]; ~i; i = ne[i]) Y = e[i];
dfs(X, Y, deg[Y], 1);
(ans *= k) %= mod;
printf("Case #%d: %lld\n", id, ans);
}
int main() {
scanf("%d", &T);
for (int id = 1; id <= T; id++) solve(id);
return 0;
}