解题报告 『可达性统计(拓扑排序 + bitset)』

原题地址

题不难,但是让我获悉了bitset这种神奇的操作。

代码实现如下:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (register int i = a; i <= b; i++)
#define per(i, a, b) for (register int i = a; i >= b; i--)

const int maxn = 3e4 + 5;

int n, m, cnt = 0, num_edge = 0;
int ans[maxn], deg[maxn], head[maxn], topo[maxn];

queue<int> q;
bitset<maxn> p[maxn];

struct node {
    int to, nxt;
}edge[maxn];

void origin() {memset(head, -1, sizeof(head));}

int read() {
    int x = 0, flag = 0;
    char ch = ' ';
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') {
        flag = 1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return flag ? -x : x;
}

void addedge(int from, int to) {
    edge[++num_edge].nxt = head[from];
    edge[num_edge].to = to;
    head[from] = num_edge;
}

void topo_sort() {
    rep(i, 1, n)
        if (!deg[i]) q.push(i);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        topo[++cnt] = u;
        for (register int i = head[u]; ~i; i = edge[i].nxt) {
            int v = edge[i].to;
            if (!(--deg[v])) q.push(v);
        }
    }
}

void write(int x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int main() {
    origin();
    n = read(), m = read();
    rep(i, 1, m) {
        int u, v;
        u = read(), v = read();
        addedge(u, v);
        deg[v]++;
    }
    topo_sort();
    rep(i, 1, n) p[i][i] = 1;
    per(i, cnt, 1) {
        int u = topo[i];
        for (register int j = head[u]; ~j; j = edge[j].nxt) {
            int v = edge[j].to;
            p[u] |= p[v];
        }
        ans[u] = p[u].count();
    }
    rep(i, 1, n) {
        write(ans[i]);
        printf("\n");
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Kirisame-Marisa/p/10804698.html