📅  最后修改于: 2023-12-03 15:28:37.912000             🧑  作者: Mango
给出两个整数 $n$ 和 $m$,代表一个具有 $n$ 个门和 $m$ 个纽扣的房间。门编号从 $1$ 到 $n$,纽扣编号从 $1$ 到 $m$。每个门要么待在关闭的状态,要么待在打开的状态。如果门 $i$ 的状态是打开的,那么每次运行门 $i$ 将使其状态更改。
如果门 $i$ 目前处于关闭状态,那么门 $i$ 只能从纽扣 $j$ 打开,其中 $(i \mod j = 0)$。如果门 $i$ 目前处于打开状态,则纽扣 $i$ 可以关掉门 $i$,并将其状态更改为关闭状态。每个纽扣最多只能使用一次。
你的任务是设计一个含有 $m$ 个布尔值输入的电路,电路中第 $i$ 个布尔值为真当且仅当使用纽扣 $i$ 可以打开所有的门(若为假表示不能打开)。在电路中,每个布尔变量的值只能计算一次(即不能重复计算)。
第一行输入两个正整数 $n$ 和 $m$,代表门数和纽扣数。
接下来的 $m$ 行中,每行输入两个正整数 $a$ 和 $b$,代表纽扣 $a$ 能不能打开门 $b$。
输出一个长为 $m$ 的 01 序列,代表电路的输出。对于所有的 $i \in [1,m]$,输出布尔变量 $x_i$ 的值,表示使用纽扣 $i$ 是否可以打开所有门。
6 4
1 2
2 4
3 3
4 2
0111
我们可以用图来表示这个问题,建立一个有 $n$ 个节点的图,每个节点表示一个门,节点 $i$ 有一个从点 $i$ 到点 $j$ 的有向边,当 $i \mod j =0$ 时,还有从点 $j$ 到点 $i$ 的无向边,若 $i$ 可以通过某些边到达 $j$,则 $i$ 可以通过纽扣 $j$ 打开。问题就转化为找出对于所有的 $i(1\le i\le m)$,是否存在一条路径从点 $i$ 到所有的点。这是一个带权 DAG 上所有节点可达性问题,可以使用 tarjan 算法求解。
具体而言,对于一个有向加权图 $G=(V,E,w)$,给每个节点 $x$ 赋初始标号 $dfn_x$ 和最小标号 $low_x$。一个节点 $x$ 的祖先是在 DFS 树中 $x$ 的前趋中当前 DFS 树的最后访问节点 $u$。如果 $u$ 到 $x$ 有一条回溯边,那么 $u$ 是 $x$ 在 DFS 树上的祖先。否则存在 $u$ 在 $x$ 的某个后代 $y$ 的子树中。对于节点 $x$,可以找到它的最小祖先 $m_x$,满足 $m_x$ 可以到达除 $x$ 以外的所有点,当且仅当满足 $m_x$ 的出度为 $\deg(m_x) > 0$ 或者 $m_x$ 到 $m_x$ 的所有后继都可以到达 $m_x$ 的所有祖先,其中至少存在一个 $k$ 满足 $\deg(k) > 1$ 或者 $k$ 是 DFS 树的根节点。