现在的位置: 首页 > 综合 > 正文

爱在心中 (强联通分量)

2017年11月16日 ⁄ 综合 ⁄ 共 1142字 ⁄ 字号 评论关闭
#include <iostream>
#include <cstdio>
using namespace std;
struct edge {
    int to, next;
} e[50001], d[50001];
int n, m, ind, top, cnt, scc, dfn[10001], low[10001], head[10001], h[10001],
    belong[10001], q[10001], hav[10001];
bool inq[10001];
void tarjan(int x) {
    dfn[x] = low[x] = ++ind;
    q[++top] = x;
    inq[x] = 1;
    for (int i = head[x]; i; i = e[i].next)
        if (!dfn[e[i].to])
            tarjan(e[i].to), low[x] = min(low[x], low[e[i].to]);
        else if (inq[e[i].to])
            low[x] = min(low[x], dfn[e[i].to]);
    int now = 0;
    if (low[x] == dfn[x]) {
        scc++;
        while (now != x) {
            now = q[top--];
            inq[now] = 0;
            belong[now] = scc;
            hav[scc]++;
        }
    }
}

void rebuild() {
    for (int i = 1; i <= n; i++) {
        for (int j = head[i]; j; j = e[j].next)
        if (belong[i] != belong[e[j].to]) {
            d[++cnt].to = belong[e[j].to];
            d[cnt].next = h[belong[i]];
            h[belong[i]] = cnt;
        }
    }
}

void pre() {
    for (int i = 1; i <= n; i++)
        if (!dfn[i])
            tarjan(i);
    rebuild();
}

void work() {
    int ans = 0;
    for (int i = 1; i <= scc; i++)
        if (hav[i] > 1)
            ans++;
    printf("%d\n", ans);
    ans =  - 1;
    for (int i = 1; i <= scc; i++)
    if (!h[i]) {
        if (ans !=  - 1 || hav[i] == 1) {
            ans =  - 1;
            break;
        } else
            ans = i;
    }
    if (ans ==  - 1)
        printf("%d\n", ans);
    else
    for (int i = 1; i <= n; i++) {
        if (belong[i] == ans)
            printf("%d ", i);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[i].to = y;
        e[i].next = head[x];
        head[x] = i;
    }
    pre();
    work();
    return 0;
}

抱歉!评论已关闭.