hihoCoder #1343 Stable Members
题目大意$\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的更多相关文章
- hihocoder 1343 : Stable Members【拓扑排序】
hihocoder #1343:题目 解释:一个学习小组,一共有N个学员,一个主管.每个学员都有自己的导师(一个或者多个),导师可以是其他学员也可以是主管.每周学员都要把自己的学习报告和收到的报告提交 ...
- hihoCoder1343 : Stable Members【BFS拓扑排序】
题目链接:https://hihocoder.com/problemset/problem/1343 #1343 : Stable Members 时间限制:10000ms 单点时限:1000ms 内 ...
- scala 2.11.x/spec/03-types.md
scala/spec/03-types.md title: Types layout: default chapter: 3 --- Types Type ::= FunctionArgTypes ' ...
- HDOJ 1914 The Stable Marriage Problem
rt 稳定婚姻匹配问题 The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 6553 ...
- 【POJ 3487】 The Stable Marriage Problem (稳定婚姻问题)
The Stable Marriage Problem Description The stable marriage problem consists of matching members o ...
- [POJ 3487]The Stable Marriage Problem
Description The stable marriage problem consists of matching members of two different sets according ...
- POJ 3487 The Stable Marriage Problem(稳定婚姻问题 模版题)
Description The stable marriage problem consists of matching members of two different sets according ...
- 龙芯 3A4000 安装 Debian stable
2022-01-17 版权声明:原创文章,未经博主允许不得转载 3A5000 开始,龙芯转向 loongarch ,新的架构虽然甩掉了历史包袱,但也需要一段时间来积累生态.在这半年多的时间里, loo ...
- 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 ...
随机推荐
- iOS消息体系架构详解-融云即时通讯云
iOS SDK 体系架构 本文档将详细介绍融云的 SDK 产品架构和消息体系,以便于您更深入的了解融云并更快速的开发自己的产品. 融云 SDK 系统架构 IMKit IMKit 的功能主要是封装各种界 ...
- 徒手教你使用zookeeper编写服务发现
zookeeper是一个强一致[不严格]的分布式数据库,由多个节点共同组成一个分布式集群,挂掉任意一个节点,数据库仍然可以正常工作,客户端无感知故障切换.客户端向任意一个节点写入数据,其它节点可以立即 ...
- 在DataGridView控件中验证数据输入
实现效果: 知识运用: DataGridView控件的公共事件CellValidating //将System.Windows.Forms.DataGridViewCellValidatingEven ...
- 超全面Java 面试题(2.1)
这部分主要是开源JavaEE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts2已经是明日黄花,在这里就不讨论Struts2的面试题,此外, ...
- thinkcmf常用标签
1.图片地址:{:cmf_get_image_url($vo.icon)} 2.模板控件 模板变量调用:$theme_vars.title <widget name="aboutUs& ...
- 转载:将画布(canvas)图像保存成本地图片的方法
之前我曾介绍过如何将HTML5画布(canvas)内容转变成图片形式,方法十分简单.但后来我发现只将canvas内容转变成图片输出还不够,如何能将转变后的图片保存到本地呢? 其实,这个方法也是非常简单 ...
- 命令行下创建MySQL数据库与创建用户以及授权
先以root用户登录mysql: C:\Users\XXX>mysql -u root -p 输入密码后登录,接下来操作如下: 1.创建数据库 语法:create schema [数据库名称] ...
- Python中的端口协议之基于UDP协议的通信传输
UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较) 3.利用socketserver模块实现udp传输协议的并 ...
- HDU - 6199 gems gems gems (DP)
有n(2e4)个宝石两个人轮流从左侧取宝石,Alice先手,首轮取1个或2个宝石,如果上一轮取了k个宝石,则这一轮只能取k或k+1个宝石.一旦不能再取宝石就结束.双方都希望自己拿到的宝石数比对方尽可能 ...
- 合肥工业大学宣城校区大学生创新创业训练项目申报书:“基于Spark平台的人工智能知识的知识图谱构建”