<更新提示>

<第一次更新>


<正文>

树上匹配

Description

懒惰的温温今天上班也在偷懒。盯着窗外发呆的温温发现,透过窗户正巧能看到一棵 n 个节点的树。一棵 n 个节点的树包含 n-1 条边,且 n 个节点是联通的。树上两点之间的距 离即两点之间的最短路径包含的边数。

突发奇想的温温想要选择一个树上的边集(可以为空)删除, 使得删除后剩下的图的 最大匹配是唯一的。温温想要知道满足条件的边集的数量。满足条件的边集数量可能很多, 请对 998244353 取模。

图的一个匹配是图的一个边子集,满足条件任意两条边都不依附于同一个节点。图的所 有匹配中,边数最多的匹配即为图的最大匹配。

Input Format

第一行一个整数 n。

接下来 n-1 行每行两个整数 ai, bi,表示节点 ai 和 bi 之间存在一条边。

2 ≤ n ≤ 3000 for 40%

2 ≤ n ≤ 300000 for 100%

Output Format

输出一个整数,表示所求的满足条件的边集数量,对 998244353 取模

Sample Input

4
1 2
1 3
1 4

Sample Output

4

解析

先转换题意:最大匹配唯一其实等价于图中的一个点要么孤立,要么属于最大匹配。

这个条件的必要性是显然的,也就是说,最大匹配唯一,该条件一定满足。同样我们也可以证明该条件的充分性:反证法,假设存在一个点,它既不孤立也不属于最大匹配,并且这个图的最大匹配唯一。我们分两种情况讨论:

\(1.\) 这个点连向的点属于最大匹配,那就与最大匹配的唯一性矛盾

\(2.\) 这个点连向的点不属于最大匹配,那就与最大匹配的极大性矛盾

所以这两个命题是等价的。

那么我们就可以考虑树形\(dp\)计数。设\(f1[x]\)代表节点\(x\)等待他的父节点与他匹配,子树\(x\)的方案数,\(f2[x]\)代表节点\(x\)孤立,子树\(x\)的方案数,\(f3[x]\)代表节点\(x\)已经与某一个儿子匹配,子树的\(x\)的方案数。然后列状态转移方程:

\[f1_{x}=\prod_{y\in son(x)}(f2_y+2f3_y)\\f2_x=\prod_{y\in son(x)}(f2_y+f3_y)\\f3_x=\sum_{y\in son(x)} \left ( \frac{\prod_{z\in son(x),z\not= y}(f2_z+2f3_z)}{f2_y+2f3_y}*f1_y \right )
\]

为什么\(f3\)都要乘\(2\),是因为当前节点\(x\)与\(f3\)这种完成状态之间的边可连可不连。关于第三个状态转移方程,其含义为选一个点\(y\)的\(f1\)状态与其匹配,剩下的同理随便选。

\(Code:\)

#include <bits/stdc++.h>
using namespace std;
const int N = 300020;
const long long Mod = 998244353;
struct edge { int ver,next; } e[N*2];
int n,t,Head[N];
long long f1[N],f2[N],f3[N];
// f1 means which node is waiting mathcing
// f2 means which node is isolated
// f3 means which node has already matched
inline void insert(int x,int y)
{
e[++t] = (edge){y,Head[x]} , Head[x] = t;
e[++t] = (edge){x,Head[y]} , Head[y] = t;
}
inline void input(void)
{
scanf("%d",&n);
for ( int i = 1; i < n; i++ )
{
int x,y;
scanf("%d%d",&x,&y);
insert( x , y );
}
}
inline long long power(long long a,long long b)
{
long long res = 1;
while ( b )
{
if ( 1 & b ) res = res * a % Mod;
a = a * a % Mod , b >>= 1;
}
return res;
}
inline void mul(long long &a,long long b) { a = a * b % Mod; }
inline void add(long long &a,long long b) { a += b; if ( a >= Mod ) a -= Mod; }
inline void dp(int x,int f)
{
f1[x] = f2[x] = 1LL;
long long val = 1LL;
for ( int i = Head[x]; i; i = e[i].next )
{
int y = e[i].ver;
if ( y == f ) continue;
dp( y , x );
mul( f1[x] , ( f2[y] + 2 * f3[y] ) % Mod );
mul( f2[x] , ( f2[y] + f3[y] ) % Mod );
mul( val , ( f2[y] + 2 * f3[y] ) % Mod );
}
for ( int i = Head[x]; i; i = e[i].next )
{
int y = e[i].ver;
if ( y == f ) continue;
long long inv = power( f2[y] + 2 * f3[y] , Mod-2 );
long long sum = val;
mul( sum , inv ) , mul( sum , f1[y] );
add( f3[x] , sum );
}
}
int main(void)
{
input();
dp( 1 , 0 );
printf("%lld\n", ( f2[1] + f3[1] ) % Mod );
return 0;
}

<后记>

『树上匹配 树形dp』的更多相关文章

  1. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  2. 『大 树形dp』

    大 Description 滑稽树上滑稽果,滑稽树下你和我,滑稽树前做游戏,滑稽多又多.树上有 n 个节点,它们构成了一棵树,每个节点都有一个滑稽值. 一个大的连通块是指其中最大滑稽值和最小滑稽值之差 ...

  3. 『战略游戏 最大利润 树形DP』

    通过两道简单的例题,我们来重新认识树形DP. 战略游戏(luoguP1026) Description Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要 ...

  4. 『没有上司的舞会 树形DP』

    树形DP入门 有些时候,我们需要在树形结构上进行动态规划来求解最优解. 例如,给定一颗\(N\)个节点的树(通常是无根树,即有\(N-1\)条无向边),我们可以选择任意节点作为根节点从而定义出每一颗子 ...

  5. 『You Are Given a Tree 整体分治 树形dp』

    You Are Given a Tree Description A tree is an undirected graph with exactly one simple path between ...

  6. 『快乐链覆盖 树形dp』

    快乐链覆盖 Description 给定一棵 n 个点的树,你需要找至多 k 条互不相交的路径,使得它们的长度之和最大 定义两条路径是相交的:当且仅当存在至少一个点,使得这个点在两条路径中都出现 定义 ...

  7. 『kamp 树形dp』

    kamp Description jz 市的云台山是个很美丽的景区,小 x 暑期到云台山打工,他的任务是开景区的大巴. 云台山景区有 N 个景点,这 N 个景点由 N-1 条道路连接而成,我们保证这 ...

  8. 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

    题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...

  9. 【BZOJ4033】[HAOI2015]树上染色 树形DP

    [BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...

随机推荐

  1. Django框架(五)-- 视图层:HttpRequest、HTTPResponse、JsonResponse、CBV和FBV、文件上传

    一.视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...

  2. MySQL数据库(三)--表相关操作(二)之约束条件、关联关系、复制表

    一.约束条件  1.何为约束 除了数据类型以外额外添加的约束 2.约束条件的作用 为了保证数据的合法性,完整性 3.主要的约束条件 NOT NULL # 标识该字段不能为空,默认NULL,可设置NOT ...

  3. ASS/SSA字幕格式

    [时间:2019-04] [状态:Open] [关键词:字幕,ASS,SSA,文件格式,v4 Styles,字幕特效] 0 引言 SubStation Alpha(Sub Station Alpha) ...

  4. C#中Equals 与== 的区别

    这个问题听说是大公司面试都会问的问题,以前不怎么了解,好奇心勾引我来研究一下 首先从值类型分析,先写几句简单的代码供测试用,二行语句输出的都是true, 说明==与Equals功能是相同的, 判断的都 ...

  5. 关于ID命名 一个页面唯一

    1.一般ID在一个区域内必须是唯一的.这样是一个规范而且在IE中使用JS通过ID获取这个对象永远只能获取第一个. 2.js无法找到重复的ID,用js获取时,只能得到第一个ID元素,但,如果不同的区域范 ...

  6. ESA2GJK1DH1K基础篇: 阿里云物联网平台: 云平台显示单片机采集的温湿度数据,控制设备继电器(基于GPRS模块,AT指令TCP_MQTT通信)

    实现的功能 上一节是使用的Wi-Fi模块连接的阿里云平台,这节呢咱用GPRS连接. 阿里云的设备配置还是按照上一节的,有个温度,有个湿度. 测试 一,打开单片机程序 二,根据自己的修改,然后下载进去单 ...

  7. Test of String

    1.前言 这是我出的第一套题目,话说感觉有点晚了,还是在向总安排下出的.我被安排的是字符串方面的内容,这应该相对而言是比较小众的知识点吧,但是一样的有作用的,也有很神的题目.所谓是NOIP模拟题,其实 ...

  8. Linux下进程间通信方式——信号量(Semaphore)

    1.信号量 信号量本质上是一个计数器(不设置全局变量是因为进程间是相互独立的,而这不一定能看到,看到也不能保证++引用计数为原子操作),用于多进程对共享数据对象的读取,它和管道有所不同,它不以传送数据 ...

  9. ORA-25153错误及解决办法

    出现下图错误 原因就是没有临时表空间,所以要建立临时表空间,下面的语句,记得把地址换成你自己想放的地方. alter tablespace temp add tempfile 'C:/temp.dbf ...

  10. web服务本质

    目录 django 框架引入: web框架本质 HTTP协议 多功能web服务 封装,分发处理 django 框架引入: web框架本质 web框架本质: 软件开发架构: c / s ; b/ s - ...