洛谷1726 上白澤慧音
阿新 • • 發佈:2018-11-03
原題連結
裸的\(tarjan\)找強連通分量,記錄最大強連通分量即可,注意字典序。
#include<cstdio> using namespace std; const int N = 5010; const int M = 1e5 + 10; int fi[N], di[M], ne[M], dfn[N], low[N], sta[N], bl[N], ma_si, ma_id, ma_mi, SCC, tp, ti, l; bool v[N]; inline int re() { int x = 0; char c = getchar(); bool p = 0; for (; c < '0' || c > '9'; c = getchar()) p |= c == '-'; for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0'; return p ? -x : x; } inline void add(int x, int y) { di[++l] = y; ne[l] = fi[x]; fi[x] = l; } inline int minn(int x, int y){ return x < y ? x : y; } void tarjan(int x) { int i, y; dfn[x] = low[x] = ++ti; sta[++tp] = x; v[x] = 1; for (i = fi[x]; i; i = ne[i]) if (!dfn[y = di[i]]) { tarjan(y); low[x] = minn(low[x], low[y]); } else if (v[y]) low[x] = minn(low[x], dfn[y]); if (!(low[x] ^ dfn[x])) { int mi = 1e9, s = 0; SCC++; do { y = sta[tp--]; v[y] = 0; bl[y] = SCC; mi = minn(mi, y); s++; } while (x ^ y); if (ma_si < s) { ma_si = s; ma_id = SCC; ma_mi = mi; } else if (!(ma_si ^ s) && ma_mi > mi) { ma_id = SCC; ma_mi = mi; } } } int main() { int i, n, m, x, y, z; n = re(); m = re(); for (i = 1; i <= m; i++) { x = re(); y = re(); z = re(); add(x, y); if (z ^ 1) add(y, x); } for (i = 1; i <= n; i++) if (!dfn[i]) tarjan(i); printf("%d\n", ma_si); for (i = 1; i <= n; i++) if (!(bl[i] ^ ma_id)) printf("%d ", i); return 0; }