noip模拟赛 hungary


分析:比较难的一道题,看到要求方案数,又是在一棵树上,自然就想起了树形dp.状态该怎么表示呢?首先肯定有一维状态表示以i为根的子树,考虑到i有没有匹配对答案也是有影响的,自然而然状态就出来了:f[i][0/1]表示以i为根的子树中,i取或不取的最大匹配.因为要求方案数,再开一个数组g[i][0/1]记录方案数.
接下来考虑怎么转移.如果i不选,那么它的子节点不管选不选都没关系:
f[i][0] = Σmax{f[j][0],f[j][1]},如果i要选,那么它的子节点中一定有一个没选的点k,其它点随意.
f[i][1] = max{f[k][0] + 1 + Σmax{f[j][0],f[j][1] (j != k)}}.对于g的转移就是比较常见的套路了,子树内加法原理,子树合并乘法原理.每次选肯定要选最大匹配的那种方案,所以开一个数组ans,如果f[i][0] > f[i][1],ans[i] = g[i][0]; f[i][0] < f[i][1],ans[i] = g[i][1];
f[i][0] = f[i][1],ans[i] = g[i][1] + g[i][0]. 那么g[i][0] = πans[j],i要选的话,k就不能直接用ans的值,那么g[i][1] = Σ(g[k][0] * (πans[j] / ans[k])),涉及到取模,用到了乘法逆元.
设计状态的时候想清楚当前点有哪几种状态,它们对答案有没有影响.转移的时候想想转移过来的子节点必须满足什么要求,其它的点该怎么分配.求方案数的时候要分清楚是乘法原理还是加法原理.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
const int maxn = , mod = ; typedef long long ll; int T, P, n, head[maxn], to[maxn * ], nextt[maxn * ], tot = ;
ll f[maxn][], g[maxn][], ans[maxn]; void add(int x, int y)
{
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++;
} ll qpow(ll a, ll b)
{
ll res = ;
while (b)
{
if (b & )
res = (res * a) % mod;
a = (a * a) % mod;
b >>= ;
}
return res;
} void dfs(int x, int fa)
{
f[x][] = f[x][] = ans[x] = ;
g[x][] = g[x][] = ;
bool flag = false;
ll sum = , mul = ;
for (int i = head[x]; i; i = nextt[i])
{
int v = to[i];
if (v != fa)
{
dfs(v, x);
sum += max(f[v][], f[v][]);
sum %= mod;
f[x][] += max(f[v][], f[v][]);
f[x][] %= mod;
g[x][] = g[x][] * ans[v] % mod;
mul = mul * ans[v] % mod;
flag = true;
}
}
if (!flag)
g[x][] = ;
for (int i = head[x]; i; i = nextt[i])
{
int v = to[i];
if (v != fa)
{
if (f[x][] < f[v][] + + sum - max(f[v][], f[v][]))
{
f[x][] = (((f[v][] + + sum) % mod) - max(f[v][], f[v][]) + mod) % mod;
g[x][] = g[v][] * mul % mod * qpow(ans[v],mod - ) % mod;
}
else
if (f[x][] == f[v][] + + sum - max(f[v][], f[v][]))
g[x][] = (g[x][] + g[v][] * mul % mod * qpow(ans[v],mod - ) % mod) % mod;
}
}
if (f[x][] > f[x][])
ans[x] = g[x][];
if (f[x][] < f[x][])
ans[x] = g[x][];
if (f[x][] == f[x][])
ans[x] = g[x][] + g[x][];
ans[x] %= mod;
} int main()
{
scanf("%d%d", &T, &P);
while (T--)
{
memset(head, , sizeof(head));
tot = ;
scanf("%d", &n);
for (int i = ; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs(, );
printf("%lld ", max(f[][], f[][]));
if (P == )
printf("%lld", ans[] % mod);
printf("\n");
}
return ;
}
noip模拟赛 hungary的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #52 - Thinking Bear #1 (NOIP模拟赛)
A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...
随机推荐
- Codeforces 920F. SUM and REPLACE / bzoj 3211 花神游历各国
题目大意: 一个数列 支持两种操作 1 把区间内的数变成他们自己的约数个数 2 求区间和 思路: 可以想到每个数最终都会变成2或1 然后我们可以线段树 修改的时候记录一下每段有没有全被修改成1或2 是 ...
- bzoj3661
网络流/贪心 网络流做法是对于每一列,如果一个兔子下一天继续可以存在,那么连一条容量为1的边,然后设立一个中转站,来控制可以换的数量,容量限制l.时限100s,能跑过去我的太慢了,一个点100s 正解 ...
- android 中activity 属性说明(转载)
转自:http://liuwuhen.iteye.com/blog/1759796 activity是android中使用非常平凡的一种组件,我们除了需要掌握activity中的生命周期以外,还需要掌 ...
- 在eclipse中如何在大量项目中查找指定文件(转载)
转载:http://blog.csdn.net/inowcome/article/details/6699227 在eclipse中如果希望在大量的项目中寻找指定的文件可不是一件轻松的事,还好ecli ...
- yii2表单,用惯yii1的可以看一下,有很大不同哦
使用表单 本章节将介绍如何创建一个从用户那搜集数据的表单页.该页将显示一个包含 name 输入框和 email 输入框的表单.当搜集完这两部分信息后,页面将会显示用户输入的信息. 为了实现这个目标,除 ...
- Gym - 101982A 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) A. Exam
题面 题意:你和朋友一起做了n道判断题,现在你知道你们两的答案,也知道你朋友对了k个,问你至少对了几个 题解:假设你和朋友n个答案都一样,那你是不是也对了k个,假设你和朋友有1个答案不一样,是不是,你 ...
- [Apple开发者帐户帮助]九、参考(6)支持的功能(watchOS)
watchOS扩展可用的功能取决于您的程序成员身份. 注意:对于watchOS应用程序目标,可用的功能是应用程序组和后台模式,并且不依赖于您的程序成员身份. 能力 ADP 企业 Apple开发者 应用 ...
- Java经典算法之冒泡排序(Bubble Sort)
原理:比较相邻的两个值,将值大的元素交换至右端 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数 ...
- Vue组件库elementUI 在el-row 或 el-col 上使用@click无效失效,
问题: elementUI 在el-row 或者 el-col 上使用@click失效, 解决: 在click后面加上 .native .要使用@click.native=”handler()”才行, ...
- Sql批量插入方法
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...