Loading

可达性统计

 

用f[i]带标i能到达点的数量,如果要计算u能到达的点的数量,则需要计算所有f[v1] U f[v2] U f[v3] U ......。那么可以先通过拓扑排序建出一个拓扑图,然后逆向计算,在这个过程中用到一个bitset的技巧,bitset可以建立一个长度为n的01串,然后对于某一个点x,x的串上的第i位如果是1的话就说明x能到达i,0则不能到达,这时候 f[v1] U f[v2] U f[v3] <=> f[v1] | f[v2] | f[v3]。

 1 #include <iostream>
 2 #include <vector>
 3 #include <bitset>
 4 
 5 using namespace std;
 6 #define gogo ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
 7 
 8 const string YES = "YES";
 9 const string NO = "NO";
10 
11 const int N = 10010;
12 int n, m, q[N], d[N];
13 vector<int> edge[N];
14 bitset<N> f[N];
15 
16 void Toposort() {
17     int front = 1, rear = 0;
18     for (int i = 1;i <= n;i ++) 
19         if (!d[i])
20             q[++rear] = i;
21     while (front <= rear) {
22         int t = q[front ++];
23         for (auto y : edge[t]) 
24             if (-- d[y] == 0) 
25                 q[++rear] = y;
26     }
27 }
28 
29 int32_t main() {
30     gogo;
31     
32     cin >> n >> m;
33     for (int i = 0;i < m;i ++) {
34         int a, b;
35         cin >> a >> b;
36         d[b] ++;
37         edge[a].push_back(b);
38     }
39     Toposort();
40     for (int i = n;i >= 1;i --) {
41         int j = q[i];
42         f[j][j] = 1;
43         for (auto y : edge[j])
44             f[j] |= f[y];
45     }
46     for (int i = 1;i <= n;i ++)
47         cout << f[i].count() << '\n';
48 
49     return 0;
50 }
Toposort

 

posted @ 2023-03-08 20:57  KakaDBL  阅读(40)  评论(0)    收藏  举报