题目大意$\newcommand{\SD}{\mathrm{SD}}$

给定一个 $n+1$ 个点的有向无环图,点从 $0$ 开始编号。无重边、自环,且从每个点 $u$ 都能到达 $0$ 号点。如果每条 $u\leadsto 0$ 路径($u\ne 0$)都经过点 $v$ ($v\ne 0$ 且 $v\ne u$),则称 $u$ 不稳定,否则称 $u$ 稳定。求稳定点的个数。

一个错误解法

先记录我的一个错误做法。将输入的图中的边全部反向,从 $0$ 号点开始 DFS。有向无环图在 DFS 的过程中不会出现回边(backward edge,也译作「后向边」),只有树边、前向边(forward edge)和侧向边(cross edge,也译作「横叉边」)。点 $u$ 稳定等价于「存在两条点不相交的 $0\leadsto u$ 路径」。而这个条件要是满足,那么必然出现连向 $u$ 的前向边或侧向边。在 DFS 的过程中,当发现有前向边或侧向边连向 $u$ 时,就检查当前这条 $0\leadsto u$ 路径和之前找到的完全由树边构成 $0\leadsto u$ 路径是否交叉,若无交叉,则 $u$ 稳定。可以通过类似 Tarjan 离线 LCA 算法的思路来判断上述两路径是否交叉,只要判断 $u$ 和 $0$ 是否在一个集合中(并查集),若在同一个集合中则无交叉。

代码:

#include <bits/stdc++.h>
#define rep(n) for(size_t __i = 0, __j=(n); __i < __j; ++__i)
#define rep2(i,n) for(size_t (i)=0, _i=n;(i)<_i;(i)++)
#define rep3(i,b,e) for(size_t i =(b); (i)<(e); (i)++)
#define ran(i,b,e) for(size_t (i)=(b); (i)<(e); (i)++)
#define drep2(i,n) for(size_t (i)=(n)-1; (i)>=0; (i)--)
using namespace std;
using ll=long long;
const size_t N=size_t(1e5+5); vector<size_t> g[N]; bool is_stable[N]; size_t fa[N]; size_t root(size_t x){
return x==fa[x]?x:fa[x]=root(fa[x]);
}
void unite(size_t x, size_t y){
x=root(x);
y=root(y);
fa[x]=y;
} bool vis[N];
void dfs(size_t u){
vis[u]=true;
for(auto v:g[u]) {
if (!vis[v]){
dfs(v);
unite(v,u);
}
else if (root(v) == 0) is_stable[v] = true;
}
} int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
size_t n;
cin>>n;
ran(i,1,n){
fa[i]=i; // init
size_t k;
cin>>k;
rep(k){
size_t x;
cin>>x;
g[x].push_back(i);
}
}
dfs(0);
for(auto x:g[0]) is_stable[x]=true;
int ans=0;
ran(i,1,n) ans+=is_stable[i];
cout<<ans<<'\n';
return 0;
}

这个做法是错的,下面给出一个反例:

节点编号也是节点的访问顺序。这个做法将 $3$ 号节点判为不稳定的。

题解上的做法

这道题我没想出正解。


仍考虑输入的图。

如果每条 $u\leadsto 0$ 路径($u\ne 0$)都经过 $v$ ($v\ne 0$ 且 $v\ne u$),则称 $v$ 是 $u$ 的支配点(dominator)。若 $v$ 是 $u$ 的支配点且 $v$ 是稳定的,则称 $v$ 为 $u$ 的稳定支配点(stable dominator)。

不难证明,支配点有下述性质:

性质 1

$u$ 的支配点可能不唯一,但一定分布在某条链上。

这个性质根据定义很容易证明。

性质 2

设 $v_1$、$v_2$ 是 $u$ 的两个支配点,那么或者 $v_1$ 是 $v_2$ 的支配点,或者 $v_2$ 是 $v_1$ 的支配点。

证明:

不失一般性,假设存在路径 $P\colon u\leadsto v_1\leadsto v_2\leadsto 0$ ,则必有 $v_2$ 是 $v_1$ 的支配点。若不然,即存在路径 $P'\colon v_1\leadsto 0$ 满足 $v_2$ 不在 $P'$ 上,从而 $v_2$ 也不是 $u$ 的支配点。

性质 3

若 $u$ 是不稳定的,则 $u$ 有唯一的稳定支配点。

证明:

用 $d(u)$ 表示 $u$ 到 $0$ 的最短距离。满足 $d(v)=1$ 的点 $v$ 必定是稳定的。

若 $v$ 是 $u$ 的支配点则必有 $d(v) < d(u)$ 。

由于 $u$ 的支配点的支配点也是 $u$ 的支配点,所以 $u$ 的稳定支配点必然存在。

$u$ 的稳定支配点是 $u$ 的所有支配点中距离 $0$ 号点最近的那个点。

又根据性质 $2$ 可知 $u$ 的稳定支配点唯一。

若 $u$ 不稳定,用 $\SD(u)$ 表示 $u$ 的稳定支配点。

可以证明下述定理

定理 1

$u\ne 0$ 是稳定的当且仅当:

(1) 存在弧 $(u,0)$;或者

(2) 存在两条「点(除 $u$ 外)不相交」的路径 $u\leadsto v_1$ 和 $u\leadsto v_2$ 满足 $v_1$ 和 $v_2$ 都是稳定的。

必要性是显然的,条件(2)的充分性也很容易证明。


若图中存在 $u\leadsto v$ 路径则称 $v$ 为 $u$ 的后继(successor),若图中存在弧 $(u,v)$ 则称 $v$ 为 $u$ 的直接后继(direct successor)。

具体实现就是:将图上的点拓扑排序,按照拓扑排序的逆顺序依次(根据定理 1)判断每个点是否稳定。定理 1 中的第二个条件中的 $v_1$、$v_2$ 包括:

  • $u$ 的稳定直接后继,
  • $\SD(v)$:$v$ 是 $u$ 的不稳定直接后继。

下面证明

性质 4

设 $v_1$、$v_2$ 是 $u$ 的两个不稳定的直接后继。若 $\SD(v_1)\ne SD(v_2)$,则存在两条点不相交的路径 $v_1\leadsto \SD(v_1)$ 和 $v_2\leadsto \SD(v_2)$ 。

证明:

反证法。

设 $P_1$ 是某一条 $v_1\leadsto \SD(v_1)$ 路径,令 $P_2$ 是任意一条 $v_2 \leadsto \SD(v_2)$ 路径,将路径 $P_1$、$P_2$ 上的交集记作 $V$($V \ne \emptyset$),将 $V$ 中「拓扑序最小的点」和「拓扑序最大的点」分别记为 $s(V)$ 和 $t(V)$ 。由于 $\SD(v_1)$ 是 $v_1$ 的支配点,可知 $\SD(v_1)\in V$,否则路径 $v_1 \xrightarrow{P_1} s(V)\xrightarrow{P_2} t(V) \xrightarrow{P_2} \SD(v_2)\leadsto 0$ 是一条不经过 $\SD(v_1)$ 的路径,这与 $\SD(v_1)$ 是 $v_1$ 的支配点矛盾!故 $P_2$ 经过点 $\SD(v_1)$ 。$P_2$ 是任意选取的,因而 $\SD(v_1)\ne \SD(v_2)$ 也是 $v_2$ 的稳定支配点,这又与性质 3 矛盾!所以假设不成立。

图中绿色路径表示 $P_1$,蓝色路径表示 $P_2$ 。

上述证明中有一个不严密的地方,即 $\SD(v_2)\leadsto 0$ 路径可能与 $P_1$ 相交;下面加以完善。

假设任意 $\SD(v_2)\leadsto 0$ 路径都与路径 $P_1$ 有交点;由于 $\SD(v_2)$ 是稳定的,存在一条不经过点 $\SD(v_1)$ 的 $\SD(v_2)\leadsto 0$ 路径 $P^*$,设 $w\ne\SD(v_1)$ 是 $P_1$ 与 $P^*$ 的一个交点,则 $v_1\xrightarrow{P_1} w\xrightarrow{P^*} 0$ 也是一条不经过 $\SD(v_1)$ 的路径,同样可导出矛盾。另外,容易证明,任意 $SD(v_2)\leadsto 0$ 路径与 $P_2$ 都没有除 $\SD(v_2)$ 以外的交点。

hihoCoder #1343 Stable Members的更多相关文章

  1. hihocoder 1343 : Stable Members【拓扑排序】

    hihocoder #1343:题目 解释:一个学习小组,一共有N个学员,一个主管.每个学员都有自己的导师(一个或者多个),导师可以是其他学员也可以是主管.每周学员都要把自己的学习报告和收到的报告提交 ...

  2. hihoCoder1343 : Stable Members【BFS拓扑排序】

    题目链接:https://hihocoder.com/problemset/problem/1343 #1343 : Stable Members 时间限制:10000ms 单点时限:1000ms 内 ...

  3. scala 2.11.x/spec/03-types.md

    scala/spec/03-types.md title: Types layout: default chapter: 3 --- Types Type ::= FunctionArgTypes ' ...

  4. HDOJ 1914 The Stable Marriage Problem

    rt 稳定婚姻匹配问题 The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 6553 ...

  5. 【POJ 3487】 The Stable Marriage Problem (稳定婚姻问题)

    The Stable Marriage Problem   Description The stable marriage problem consists of matching members o ...

  6. [POJ 3487]The Stable Marriage Problem

    Description The stable marriage problem consists of matching members of two different sets according ...

  7. POJ 3487 The Stable Marriage Problem(稳定婚姻问题 模版题)

    Description The stable marriage problem consists of matching members of two different sets according ...

  8. 龙芯 3A4000 安装 Debian stable

    2022-01-17 版权声明:原创文章,未经博主允许不得转载 3A5000 开始,龙芯转向 loongarch ,新的架构虽然甩掉了历史包袱,但也需要一段时间来积累生态.在这半年多的时间里, loo ...

  9. AutoMapper:Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type

    异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html 应用场景:ViewModel==>Mode映射的时候出错 AutoMappe ...

随机推荐

  1. iOS消息体系架构详解-融云即时通讯云

    iOS SDK 体系架构 本文档将详细介绍融云的 SDK 产品架构和消息体系,以便于您更深入的了解融云并更快速的开发自己的产品. 融云 SDK 系统架构 IMKit IMKit 的功能主要是封装各种界 ...

  2. 徒手教你使用zookeeper编写服务发现

    zookeeper是一个强一致[不严格]的分布式数据库,由多个节点共同组成一个分布式集群,挂掉任意一个节点,数据库仍然可以正常工作,客户端无感知故障切换.客户端向任意一个节点写入数据,其它节点可以立即 ...

  3. 在DataGridView控件中验证数据输入

    实现效果: 知识运用: DataGridView控件的公共事件CellValidating //将System.Windows.Forms.DataGridViewCellValidatingEven ...

  4. 超全面Java 面试题(2.1)

    这部分主要是开源JavaEE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts2已经是明日黄花,在这里就不讨论Struts2的面试题,此外, ...

  5. thinkcmf常用标签

    1.图片地址:{:cmf_get_image_url($vo.icon)} 2.模板控件 模板变量调用:$theme_vars.title <widget name="aboutUs& ...

  6. 转载:将画布(canvas)图像保存成本地图片的方法

    之前我曾介绍过如何将HTML5画布(canvas)内容转变成图片形式,方法十分简单.但后来我发现只将canvas内容转变成图片输出还不够,如何能将转变后的图片保存到本地呢? 其实,这个方法也是非常简单 ...

  7. 命令行下创建MySQL数据库与创建用户以及授权

    先以root用户登录mysql: C:\Users\XXX>mysql -u root -p 输入密码后登录,接下来操作如下: 1.创建数据库 语法:create schema [数据库名称] ...

  8. Python中的端口协议之基于UDP协议的通信传输

    UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较)        3.利用socketserver模块实现udp传输协议的并 ...

  9. HDU - 6199 gems gems gems (DP)

    有n(2e4)个宝石两个人轮流从左侧取宝石,Alice先手,首轮取1个或2个宝石,如果上一轮取了k个宝石,则这一轮只能取k或k+1个宝石.一旦不能再取宝石就结束.双方都希望自己拿到的宝石数比对方尽可能 ...

  10. 合肥工业大学宣城校区大学生创新创业训练项目申报书:“基于Spark平台的人工智能知识的知识图谱构建”