可达性统计
用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 }

浙公网安备 33010602011771号