HDU-2767 Proving Equivalences (Tarjan)

Proving Equivalences (HDU - 2767)
在这里插入图片描述

using namespace std;
typedef long long ll;
const int N = 1e4+5;
const int M = 1e5+5;

struct E {
    int to, next;
} e[M];

int H[N], tot;

int S[N], top;
int dfn[N], low[N], bel[N], idx, scc;

int T, n, m;
int u, v;

int id[N], od[N];

void add(int from, int to) {
    e[tot] = {to, H[from]};
    H[from] = tot++;
}

void dfs(int u) {
    dfn[u] = low[u] = ++idx;
    S[++top]=u;

    for(int i=H[u]; ~i; i=e[i].next) {
        int v = e[i].to;
        if(!dfn[v]) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if(!bel[v])
            low[u] = min(low[u], dfn[v]);
    }
    if(low[u]==dfn[u]) {
        scc++;
        int t;
        do {
            t=S[top--];
            bel[t]=scc;
        } while(t!=u);
    }
}

void tarjan() {
    memset(dfn, 0, sizeof(dfn));
    memset(bel, 0, sizeof(bel));
    idx = scc = top = 0;
    for(int i=1; i<=n; i++) {
        if(!dfn[i])
            dfs(i);
    }
}

int solve() {
    if(scc==1)
        return 0;

    memset(id, 0, sizeof(id));
    memset(od, 0, sizeof(od));

    for(int u=1; u<=n; u++) {
        for(int i=H[u]; ~i; i=e[i].next) {
            int v = e[i].to;
            if(bel[u]!=bel[v]) {
                od[bel[u]]++;
                id[bel[v]]++;
            }
        }
    }

    int a=0, b=0;
    for(int i=1; i<=scc; i++) {
        a+=!id[i];
        b+=!od[i];
    }
    return max(a, b);
}

int main(void) {
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m);
        memset(H, -1, sizeof(H));
        tot = 0;
        for(int i=0; i<m; i++) {
            scanf("%d%d", &u, &v);
            add(u, v);
        }
        tarjan();
        printf("%d\n", solve());
    }
    return 0;
}


原文链接:加载失败,请重新获取