hdu 4661 Message Passing(树形dp)
来源:互联网 发布:协同过滤推荐算法 编辑:程序博客网 时间:2024/05/16 07:59
题目链接:hdu 4661 Message Passing
解题思路
考虑以每个位置为第一个汇总的点,即根节点。然后类似村名排队的计数。
代码
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;typedef long long ll;const int mod = 1e9 + 7;const int maxn = 1000000;int fac[maxn + 5], inv[maxn + 5];int pow_mod(ll x, int n) { ll ret = 1; while (n) { if (n&1) ret = ret * x % mod; x = x * x % mod; n >>= 1; } return ret;}void presolve() { fac[0] = 1; for (int i = 1; i <= maxn; i++) fac[i] = 1LL * i * fac[i-1] % mod; inv[maxn] = pow_mod(fac[maxn], mod-2); for (int i = maxn-1; i >= 0; i--) inv[i] = 1LL * (i+1) * inv[i+1] % mod;}int N, ans, sz[maxn + 5];vector<int> G[maxn + 5];ll dp[maxn + 5];ll C(int n, int k) { if (k > n || k < 0 || n < 0) return 0; return 1LL * fac[n] * inv[k] % mod * inv[n-k] % mod;}ll dfs (int u, int f) { ll& ret = dp[u]; ret = 1; sz[u] = 0; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; ret = ret * dfs(v, u) % mod; sz[u] += sz[v]; } int s = sz[u]; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; ret = ret * C(s, sz[v]) % mod; s -= sz[v]; } sz[u]++; return ret;}void dfs(int u, int f, ll k) { // k 为以u为根对应的反向树有多少种方式 ll ret = k; k = (k * dp[u]) % mod; int s = N-1; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; // 扣除现在枚举的子树 ll iv = k * pow_mod(dp[v] * C(sz[u]-1, sz[v]) % mod, mod-2) % mod; dfs(v, u, iv * C(N-sz[v]-1, sz[u]-sz[v]-1) % mod); ret = ret * C(s, sz[v]) % mod * dp[v] % mod; s -= sz[v]; } ans = (ans + ret * ret % mod) % mod;}int main () { presolve(); int cas; scanf("%d", &cas); while (cas--) { scanf("%d", &N); int u, v; for (int i = 1; i <= N; i++) G[i].clear(); for (int i = 1; i < N; i++) { scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } ans = 0; dfs(1, 0); dfs(1, 0, 1); printf("%d\n", ans); } return 0;}
0 0
- hdu 4661 Message Passing(树形dp)
- hdu 4661 Message Passing(树形dp)
- hdu 4661 Message Passing(树形dp)
- hdu 4661 Message Passing - 树形dp
- Hdu-4661 Message Passing(树形DP)
- hdu 4661 Message Passing(树形DP&组合数学)
- Hdu 4661 Message Passing(树形DP,扩展欧几里得)
- hdu 4661 Message Passing 树形dp (2013多校联合)
- 2013 多校第六场 hdu 4661 Message Passing(树形DP+拓展欧几里得)
- HDU 4661 Message Passing
- hdu 4661Message Passing
- HDU 4661 Message Passing
- hdu 4661 Message Passing (思维 dp求拓扑排序数)
- HDU 4661 Message Passing 【Tree】
- 逆元+树形dp-memset-hdu4661-Message Passing
- HDOJ 4661: Message Passing
- HDU 3410Passing the Message
- HDU 3410 Passing the Message
- lightoj 1369 - Answering Queries 【思维】
- android stuido离线更新的两种方式(亲测可用)
- 找出一串字符里出现次数最多的字符
- 关于web.xml,你知道多少?
- qq侧滑菜单的简单实现
- hdu 4661 Message Passing(树形dp)
- Android如何获取asset目录下所有文件的路径
- 在qt中安装使用mysql
- hdu 4662 MU Puzzle(水)
- 愤怒的小鸟-物理世界Box2d(1)-静态刚体的创建
- c++虚函数
- Course Schedule
- 操作系统与网络实现 之七
- 深入浅出 React Native:使用 JavaScript 构建原生应用