首页 > 编程语言 >noi.ac#15 题解

noi.ac#15 题解

时间:2022-09-05 20:46:18浏览次数:104  
标签:子树 15 最大 c# 题解 sum 不选 匹配 必选

做了一下午还多,完全独立完成。

题意很简单:给树加一条边使得最大匹配数增加1。

什么样的边 \((a,b)\) 满足条件呢?很明显,当且仅当存在一个最大匹配不选 \(a,b\)。此时加上 \(a,b\) 边后,\((a,b)\) 构成新的匹配,匹配数 \(+1\)。

我们把它变成 “存在一个最大匹配不选 \(a\)” 且 “存在一个最大匹配不选 \(b\)”。这事就好做了,删 \(a\) 后重新算最大匹配。树的最大匹配可以dp做,\(O(n)\)。这样再加上枚举就是 \(O(n^2)\) 的。假设这样的点叫做 “可不选点”,设 \(c\) 为“可不选点”的数量,答案就是 \(c(c-1)/2\)。

最大匹配的做法:

设 \(f(u,0/1)\) 表示 \(u\) 子树中的最大匹配数,\(u\) 不选/选(强制)。

\(f(u,0)=\sum f(v,0/1),f(u,1)=\max\{f(v,0)+\sum\limits_{v'\neq v}f(v',0/1)\}\)

\(f(u,1)\) 那个转移的意思是,既然 \(u\) 要选,那肯定要和其中一个儿子匹配,枚举和儿子 \(v\) 匹配,\(v\) 必须在子树里不选,而其它的儿子可以选或不选都行。

最后答案自然是 \(f(1,0/1)\),设 \(1\) 为树的根。

很遗憾这样不对。因为我们最开始做的转化不对。这事很好理解,因为“可以不选”并非独立的,可能我不选某个点的时候,就必须要选另外的某个点了。最简单的反例是一个三个点的链 \((1,2),(2,3)\)。最大匹配显然为 \(1\),但是不选 \(1\) 就要选 \(3\) ,不选 \(3\) 就要选 \(1\),虽然 \(1\) 和 \(3\) 都是 “可不选点”,但它俩不能同时不被选。简单来说,“可不选”不满足“合并性”,“全可不选”不代表“可全不选”。

因此正确的做法是:枚举 \(a,b\) 并删除,求剩下的树的匹配数,看是否不变。\(O(n^3)\)。

我们分两步做。枚举 \(a\) ,并删除,求匹配数看是否不变(如果这里就变了就不用再枚举 \(b\) 了)。若不变(此时树被切成了若干子树),枚举 \(b\) 并删除,此时看 \(b\) 所在的那个子树的匹配数是否不变即可,其它子树就不用看了因为没受影响一定不变。

那相当于求这样的一个东西:对于每个“可不选点”,把它切掉后剩下若干个子树,求每个子树里“可不选点”数量的和。

容易想到在dp时顺便记录下“可不选点”的数量,设为 \(g(u,0/1)\)。我们尝试写出 \(g\) 的转移式,发现了几个问题:

  • \(g\) 超级难转移,虽然也不是不可以转移
  • 注意到我们还需要做换根dp,那就得支持减去一个子树。本来做 \(f\) 就只能用 set 维护后面的 max 勉强支持减,\(g\) 比 \(f\) 还复杂,这里笔者想不下去了,我认为要对 \(g\) 做换根dp是相当困难的。

总的来说就是十分困难。(事实上,我一半时间就是在搞这个,发现搞不出来)

一条路走不通了,试试看换条路走。哪里可以“换条路”呢?我们知道,在二分图中,最大匹配数+最大独立集=n。从而转化为考虑最大独立集。

最大独立集相关dp:

最大独立集的dp比最大匹配的dp简单很多,这也是转化成最大独立集的原因。

\(f(u,0/1)\) 表示 \(u\) 子树里,\(u\) 不选/选,最大独立集。
\(f(u,0)=\sum f(v,0/1),f(u,1)=1+\sum f(v,0)\)

每个 \(v\) 贡献是独立的,很容易进行减法从而支持换根dp。

加一条边匹配数增加 \(1\),由于 \(n\) 不变,就相当于最大独立集数减小 \(1\)。最大独立集减小 \(1\),当且仅当 \(a,b\) 都是最大独立集必选的点。此时,原来可以(且必须)选 \(a,b\),现在它俩只能二选一了,最大独立集减小 \(1\)。

和“可不选”不一样,一个必须选,另一个必须选,那么两个就都是必须选的,它具有 “合并性”,“全必选”等价于“必全选”。此时答案就是必选点个数选 \(2\) 个的方案数。

写出来发现又不对。这回又哪里不对了?仔细看一下,最大匹配数+最大独立集=n 只在二分图中成立,加一条边万一出来个奇环,就不是二分图了。不过加出来是偶环就是对的。

观察数据发现这样算出来总是偏大的并且大的不多。多算的也很明确,就是加一条边后,最大独立集减少了一个但是匹配数不变的方案数。此时由于 \(n\) 不变,最大独立集+最大匹配数=n-1 ,并且生成了一个 “奇环基环树”。

从而我们有必要研究什么样的“奇环基环树”的最大独立集+最大匹配数=n-1。研究一会发现无论怎么样的结论都很难解决原问题,因为结论都是基于环上的每个子树的,而我们很难把这个子树提取出来。

实不相瞒,我另一半时间就花在这了。

我们重新回想一下,发现有这样一个东西:

我们分两步做。枚举 \(a\) ,并删除,求匹配数看是否不变(如果这里就变了就不用再枚举 \(b\) 了)。若不变(此时树被切成了若干子树),枚举 \(b\) 并删除,此时看 \(b\) 所在的那个子树的匹配数是否不变即可,其它子树就不用看了因为没受影响一定不变。

这里删除后求匹配数都是在树上求的。此时还没加边,可以使用 “最大独立集+最大匹配数=n” 的结论。

注意删了一个点后,点数就变成 \(n-1\) 了,此时匹配数不变意味着最大独立集减小 \(1\),那也就是这个点是必选点。

从而,边 \((a,b)\) 满足条件,当且仅当: \(a\) 是(最大独立集的)必选点,且 \(b\) 在 \(a\) 子树里也是必选点。

参考上面那个没做下去的思路,我们维护 \(g(u,0/1)\) 表示在 \(f(u,0/1)\) 情况下的必选点个数。但我们发现有一个问题:如果 \(f(u,0)=f(u,1)\), 那要维护两种情况的必选点的交集。这不是问题,我们再设一个状态 \(g(u,2)\) 表示总的必选点数。当一边大时,就是那一边的 \(g\),否则表示交集。

那可以写出转移:\(g(u,0)=\sum g(v,2)\),\(g(u,1)=\sum g(v,0)\)。\(g(u,2)\) 是难点。

当 \(f(u,0)>f(u,1)\) 时,\(g(u,2)=g(u,0)\); 当 \(f(u,1)>f(u,0)\) 时,\(g(u,2)=g(u,1)\)。

否则就是最麻烦的情况。此时 \(f(u,0)=f(u,1)\),也就是说 \(\sum f(v,0/1)=1+\sum f(v,0)\)

对于每个 \(v\),它可能会选择 \(\max(f(v,0),f(v,1))\) (即 \(f(v,0/1)\))或者 \(f(v,0)\)。当 \(f(v,0)\ge f(v,1)\) 时,这俩都是选 \(f(v,0)\)。此时必选点数贡献 \(g(v,0)\)。

否则就是说 \(f(v,0)<f(v,1)\)。那它可能选 \(1\) 也可能选 \(0\)。必选点数贡献 \(g(v,2)\) ... 吗?

此时我们发现它的 \(g(v,2)=g(v,1)\),但我们希望它是一个交集。

再记一个状态 \(s(u)\) 表示,选 \(0\) 和选 \(1\) 的必选点的交集,不管 \(f(u,0)\) 和 \(f(u,1)\) 的大小关系。 那此时应该是贡献一个 \(s(u)\)。

我们发现上面求的这个东西是 \(f(u,0)=f(u,1)\) 情况下的 \(g(u,2)\),其实就是 \(s(u)\)。加上 \(s(u)\) 后,推一推发现,转移完整了。长这样:

\[g(u,0)=\sum g(v,2)\\ g(u,1)=\sum g(v,0)\\ s(u)=\sum f(v,0)\ge f(v,1)?g(v,0):s(v)\\ g(u,2)= \begin{cases} g(u,0) & if.\quad f(u,0)>f(u,1)\\ g(u,1) & if.\quad f(u,1)>f(u,0)\\ s(u) & if.\quad f(u,1)=f(u,0) \end{cases} \]

虽然它看起来十分丧心病狂,但也比匹配的那个转移简单很多,而且它有一个十分优秀的性质:贡献关于每个 \(v\) 独立。

从而我们容易写出一个换根dp (建议用结构体封装加和减,会十分简单)。

记 \(f',g',s'\) 表示全局信息,即以 \(u\) 为根,整棵树的 \(f,g,s\)。举个例子 \(f'(u,0)\) 就是整颗树,不选 \(u\),最大独立集。它也就是删除 \(u\) 后的最大独立集。它可以换根dp得到。

关于如何求答案也很显然了:枚举必选点 \(a\) (即 \(f'(a,0)<f'(a,1)\)),求它的每个子树里有多少必选点,加起来即可。下面的子树直接用 \(g\),但还有一个外子树,用 \(fa[a]\) 的全局信息减去 \(a\) 的信息即可得到。

代码

标签:子树,15,最大,c#,题解,sum,不选,匹配,必选
From: https://www.cnblogs.com/LightningUZ/p/16659492.html

相关文章

  • 什么是CSS?
    CSS简介CSS指的是层叠样式表(CascadingStyleSheet),它描述了如何在屏幕、纸张或其他媒体上显示HTML元素CSS节省了大量工作。样式定义通常保存在外部.css文件中......
  • P5664[CSP-S2019] Emiya 家今天的饭 (dp + 计数)
     P5664[CSP-S2019]Emiya家今天的饭(dp+计数)题目传送门题目大意:给定一个大小为\(n*m\)的表格,其中\(a_{i,j}\)表示用第\(i\)种烹饪方式并且有第\(j\)......
  • 【题解】[SDOI2009] 虔诚的墓主人
    题意传送门\(N\timesM\)的矩形,格点是共\(W\)棵常青树或墓地。对于一块墓地,它的虔诚度为让它正上下左右各恰有\(k\)棵常青树的方法数量。求出整个矩形公墓的虔诚度总......
  • Typescript类型体操 - ReplaceAll
    答案中文实现ReplaceAll<S,From,To>将一个字符串S中的所有子字符串From替换为To。例如typereplaced=ReplaceAll<'types','',''>//期望是'types'......
  • 「postOI」Colouring Game
    题意有\(n\)个格子排成一行,一开始每个格子上涂了蓝色或红色。Alice和Bob用这些格子做游戏。Alice先手,两人轮流操作:Alice操作时,选择两个相邻的格子,其中至少要有......
  • Rust 如何实现 async/await
    目录FutureWake&Context为什么需要executor?什么是waker?async/awaitExecutorWakerstruct到ArcWaketraitFuturesUnordered单线程executor线程池executor总结异......
  • Collections.sort排序方法的最简化写法
    假定按照Number对象的Id字段进行排序正序排序Collections.sort(resultList,Comparator.comparing(Number::getId));逆序排序Collections.sort(resultList,Comparato......
  • 题解【CF1025D Recovering BST】
    题目传送门肉眼观察题。设\(f_{i,j,k}\)表示区间\([i,j]\)的根为\(k\)时能否还原。这样枚举一个根\(k\),分别枚举两个儿子在两个区间的位置转移就好了,由于两个儿子......
  • nvm安装(mac系统)
    安装命令curl-o-https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh|bash在住目录下添加~/.zshrc文件,文件内容为exportNVM_DIR="$([-z"${XDG_CON......
  • mariadb直到10.4版本才有Optimizer Trace, 之前的版本执行'SET optimizer_trace='enabl
    mariadb知道10.4版本才有OptimizerTrace,之前的版本执行'SEToptimizer_trace='enabled=on';'会返回错误https://mariadb.com/resources/blog/optimizer-trace-in-maria......