Author: loop3r
Date: 20260323
tag: 拓扑排序
link: https://www.luogu.com.cn/problem/P10480问题描述
给定一张
输入格式
第一行两个整数
输出格式
输出共
输入 #1
10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9输出 #1
1
6
3
3
2
1
1
1
1
1说明/提示
测试数据满足
分析
设从
即从
这启发我们可以先用拓扑排序求出一个拓扑序,然后根据拓扑序倒序计算每个点的
直接计算是不行的,这是我们考虑状态压缩,使用一个
这样的话对集合求并就是按位或操作,最后每个
参考代码
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 30010;
vector<int> e[N], t;
int n, m, din[N];
bitset<N> f[N];
void topoSort() {
queue<int> q;
for (int i = 1; i <= n; i++) {
if (!din[i]) q.push(i);
}
while (!q.empty()) {
int u = q.front();
q.pop();
t.push_back(u);
for (int v : e[u]) {
din[v]--;
if (!din[v]) {
q.push(v);
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
int u, v; cin >> u >> v;
e[u].push_back(v);
din[v]++;
}
topoSort();
for (int i = t.size() - 1; i >= 0; i--) {
int u = t[i];
f[u][u] = 1;
for (int v : e[u]) {
f[u] |= f[v];
}
}
for (int i = 1; i <= n; i++) {
cout << f[i].count() << endl;
}
return 0;
}