1 条题解
-
0
自动搬运
来自洛谷,原作者为

james1BadCreeper
nothing is but what is not搬运于
2025-08-24 22:17:45,当前版本为作者最后更新于2023-10-16 18:39:53,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
注意到图是一个 DAG,因此对于一条边 ,如果删了这条边依然存在 的间接路径,那么这条边必定被删去。
对于每个点求出它能到达的点和能到达它的点(不含自己)。如果 能到达的点和能到 的点有交集,那么这条边可以被删去。
前者每个点维护一个
bitset,按照拓扑序从大到小转移即可。后者建反图后跟前者一样。时间复杂度 。#include <bits/stdc++.h> using namespace std; int n, m; int u[100005], v[100005], in[30005], a[30005]; vector<int> G[30005], E[30005]; bitset<30005> to[30005], fr[30005]; void Kahn(void) { queue<int> q; int tot = 0; for (int i = 1; i <= n; ++i) if (!in[i]) q.push(i); while (!q.empty()) { int u = q.front(); q.pop(); a[++tot] = u; for (int v : G[u]) if (--in[v] == 0) q.push(v); } } int main(void) { ios::sync_with_stdio(0); cin >> n >> m; for (int i = 1; i <= m; ++i) { cin >> u[i] >> v[i]; G[u[i]].emplace_back(v[i]); E[v[i]].emplace_back(u[i]); ++in[v[i]]; } Kahn(); for (int i = n; i >= 1; --i) { int u = a[i]; for (int v : G[u]) to[u][v] = 1, to[u] |= to[v]; } for (int i = 1; i <= n; ++i) { int u = a[i]; for (int v : E[u]) fr[u][v] = 1, fr[u] |= fr[v]; } int ans = 0; for (int i = 1; i <= m; ++i) ans += (to[u[i]] & fr[v[i]]).any(); cout << ans << "\n"; return 0; }
- 1
信息
- ID
- 5161
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者