题目描述
给定一张含有 $N$ 个节点的 有向无环图(题中没有明说,但是由于没有不合法情况,故可以知道),节点编号从 $1$ 到 $N$。只有编号在 $1$ 到 $L$ 之间的 $L$ 个节点出度不为 $0$。保证编号在 $L+1$ 到 $N$ 之间的 $N-L$ 个节点入度均不为 $0$。
现在,将点 $1$ 的点权设为 $1$,并重复执行以下操作,直至编号在 $1$ 到 $L$ 中的所有节点点权均为 $0$ 为止:
- 选出点 $x$,满足 $1\le x\le L$,且点 $x$ 的点权大于 $0$。
- 对于每一条从 $x$ 出发的有向边,将到达的节点的点权加上 $x$ 的点权。
- 将点 $x$ 的点权设为 $0$。
在所有操作结束后,回答下面两个问题:
- 编号在 $L+1$ 到 $N$ 之间的所有点的点权和是多少?由于结果可能很大,输出其对 $10^9+7$ 取模的结果;
- 编号在 $L+1$ 到 $N$ 之间的所有点中,点权不为 $0$ 的点的个数是多少?
解析
很简单的一道题。
考虑拓扑排序,这样可以将同一节点上的所有操作一次性处理完。
记 $dp_i$ 为点 $i$ 的点权(对于编号在 $1$ 到 $L$ 之间的所有节点,其点权为操作期间所有下放到该点的点权之和),$vis_i$ 表示点 $i$ 由点 $1$ 出发是否可达。初始时 $dp_i$ 为 $1$,$vis_i$ 为 true
。
显然,$dp_i$ 为所有有边连向点 $i$ 的点的 $dp$ 值之和,$vis_i$ 为所有有边连向点 $i$ 的点的 $vis$ 值的逻辑或。
然后就是一道简单的拓扑排序+递推了。时间复杂度 $\mathcal{O}(N+\sum K)$。
代码参见这个提交记录,请勿抄袭!
别把 e[x].size()
写成 e[i].size()
啊
谢谢阅读,点个赞吧~