1. 程式人生 > 實用技巧 >洛谷P1726 上白澤慧音 題解 強連通分量

洛谷P1726 上白澤慧音 題解 強連通分量

題目連結:https://www.luogu.com.cn/problem/P1726

題目大意:求一個有向圖的最大強連通分量。

解題思路:tarjan。

示例程式碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5050;
int n, dfn[maxn], low[maxn], belong[maxn], idx, cnt;
bool instk[maxn];
stack<int> stk;
vector<int> g[maxn];
void tarjan(int u) {
    dfn[u] = low[u] = ++idx;
    instk[u] = true;
    stk.push(u);
    int sz = g[u].size();
    for (int i = 0; i < sz; i ++) {
        int v = g[u][i];
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (instk[v]) low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        cnt ++;
        int v;
        do {
            v = stk.top();
            stk.pop();
            instk[v] = false;
            belong[v] = cnt;
        } while (u != v);
    }
}
void solve() {
    memset(dfn, 0, sizeof(dfn));
    memset(instk, 0, sizeof(instk));
    for (int i = 1; i <= n; i ++) if (!dfn[i]) tarjan(i);
}
int m, a, b, t;
int num[maxn], maxnum, id;
int main() {
    scanf("%d%d", &n, &m);
    while (m --) {
        scanf("%d%d%d", &a, &b, &t);
        if (t == 1) g[a].push_back(b);
        else g[a].push_back(b), g[b].push_back(a);
    }
    solve();
    for (int i = 1; i <= n; i ++) {
        num[ belong[i] ] ++;
        maxnum = max(maxnum, num[ belong[i] ]);
    }
    cout << maxnum << endl;
    for (int i = 1; i <= n; i ++) {
        if (num[ belong[i] ] == maxnum) {
            id = belong[i];
            break;
        }
    }
    for (int i = 1; i <= n; i ++) if (belong[i] == id) cout << i << " ";
    return 0;
}