[WC 2007] 剪刀石头布

题意简述:给定一张图,每两点之间有一条有向边或无向边,把所有无向边定向,使图中三元环个数尽量多。\(n\le 100\).

一个重要的 \(\rm observation\) 是一个三元环不合法的 充要条件 是有且只有一个点满足三元环内入度为 \(2\)[1]。由于某个点满足三元环内入度 \(<2\) 不一定代表此三元环合法,所以正难则反,考虑用三元环总数减去不合法的三元环个数,不合法的个数可以放到点上统计。答案就是

\[\binom{n}{3}-\sum_{i=1}^n \binom{d_i}{2} \]

\(d_i\) 表示原图经定向后 \(i\) 的入度。于是我们的目标变成最小化 \(\sum \binom{d_i}{2}\),有关度数的分配,可以想到网络流。将 \(\binom{d_i}{2}\) 看成等差数列 \(\{0,1,\dots,d_i-1\}\) 求和(这一步我觉得好神),源点连边分配度数,汇点连边权值依次为 \(0,1,\dots,d_i-1\),跑最小费用最大流即可。

[UER #9] 知识网络

一些闲话:老实说,这题真的给我调 \(\rm emo\) 了。

先讲几个部分分算法吧:

  • 考虑到标签数很小,所以可以给每个标签建一个虚点,然后每个点向虚点建边权为 \(0\) 的边,虚点向每个点建边权为 \(1\) 的边;
  • 当图边数很少的时候,没有边的点就直接被所在标签更新了,这样可以缩小点的个数。

一个重要的 \(\rm observation\) 是:考虑点 \(x\) 与标签为 \(y\) 的点集 \(S\) 中每个点的最短路,一定只有 \(d\)\(x\)\(S\) 的最短路,或者 \(d+1\)。所以实际上只需要算出 \(x\) 到点集 \(S\) 的最短路,同时计算 \(S\) 中哪些点到 \(x\) 的最短路为 \(d\),就可以计算 \(f(x,y),y\in S\).

枚举标签,以对应点集 \(S\) 跑一个 \(0/1\) 边权多源点最短路,就可以处理出所有点到点集 \(S\) 的最短路。有了最短路之后,这就变成了一个可达性问题,可以用 \(\rm bitset\) 维护(注意用拓扑排序求解)。

复杂度是 \(\mathcal O(k\cdot (n+m)+n^2/w)\) 的,需要注意的是,不能直接用 \(\rm bitset\) 硬上,因为 \(\rm bitset\) 长度固定,而 \(n^2/w\) 这个复杂度是和 \(k\) 均摊的,所以每次只能开 \(|S|\) 大小的 \(\rm bitset\).

完了吗?我算是完了!码完之后才发现每次开 \(|S|\) 大小的 \(\rm bitset\) 空间会爆炸!所以实际上还要对 \(\rm bitset\) 长度进行分块!

但是我真的懒得改了,所以糊了个空间复杂度正确的做法:考虑到 \(\rm bitset\) 空间爆炸的原因是对于每种点集的最短路都需要对 \(n+k\) 个点初始化长度为 \(|S|\)\(\rm bitset\),当很多点属于一个标签时就会爆炸。而 \(S\) 中点的 \(\rm bitset\) 只有一个值,所以干脆不给 \(S\) 中点开 \(\rm bitset\),那么单次空间大概是 \(\text{S}=|S|\cdot (n-|S|)\),这是一个二次函数,它的最大值为 \(n^2/4\),就卡过去了 /kk.

我的代码:\(\text{My Submission.}\)


  1. 显然一个三元环内只有一个点能满足三元环内入度为 \(2\) 的条件。 ↩︎

posted on 2020-03-03 16:02  Oxide  阅读(170)  评论(0编辑  收藏  举报