题目大意$\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. 【UML】协作图Collaboration diagram(交互图)(转)

    http://blog.csdn.net/sds15732622190/article/details/49402269 前言         学完UML时序图,就要看一下UML协作图,因为两张图是相 ...

  2. CF Gym 100187E Two Labyrinths (迷宫问题)

    题意:问两个迷宫是否存在公共最短路. 题解:两个反向bfs建立层次图,一遍正向bfs寻找公共最短路 #include<cstdio> #include<cstring> #in ...

  3. CentOS 软RAID5

    yum install -y mdadm np1回车 tfdw mdadm --create /dev/md5 --level=5 --raid-devices=3 /dev/sdb1 /dev/sd ...

  4. IntelliJ IDEA java设置程序运行时内存

    Run/Edit Configurations   Configuration/VM options  例如:设置运行内存为:-Xmx3m -Xms3m

  5. helm install

    reference 前提:已安装k8s:v1.10.4 helm install on master(无需下载官方tar包) 链接:https://pan.baidu.com/s/1Ji3Ru1pTQ ...

  6. ssh整合思想初步 struts2与Spring的整合 struts2-spring-plugin-2.3.4.1.jar下载地址 自动加载Spring中的XML配置文件 Struts2下载地址

    首先需要JAR包 Spring整合Structs2的JAR包 struts2-spring-plugin-2.3.4.1.jar 下载地址 链接: https://pan.baidu.com/s/1o ...

  7. python入门:输出1-100之内的所有奇数和偶数(自写)

    #!/urs/bin/env python # -*- coding:utf-8 -*- #输出1-100之内的所有奇数和偶数(自写) """ 给x赋值等于1,wehil ...

  8. [译]The Python Tutorial#6. Modules

    [译]The Python Tutorial#Modules 6. Modules 如果你从Python解释器中退出然后重新进入,之前定义的名字(函数和变量)都丢失了.因此,如果你想写长一点的程序,使 ...

  9. C语言结构体初始化的四种方法(转载)

    原文:https://blog.csdn.net/ericbar/article/details/79567108 定义 struct InitMember { int first: double s ...

  10. optimize table在优化mysql时很重要

    一个表的数据量有1000W条,那么查看这么表占据的硬盘空间时会发现,数据本身是300M,索引是200M 这个时候,删除掉500W条数据,这个时候数据本身150M,而索引还是200M左右 你删除数据时, ...