namespace SHAWN { constint N = 1e6 + 7; int head[N], cnt; int qhead[N], qcnt; structnode { int to, next, lca; }; node edge[N], qedge[N]; int n, m, s; int fa[N]; bool vis[N];
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; } inlinevoidqadd(int u, int v){ qedge[++qcnt].next = qhead[u]; qedge[qcnt].to = v; qhead[u] = qcnt; } intfind(int x){ return x == fa[x] ? x : fa[x] = find(fa[x]); }
voidTarjan(int u){ fa[u] = u; vis[u] = true; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!vis[v]) { Tarjan(v); fa[v] = u; } } for (int i = qhead[u]; i; i = qedge[i].next) { int v = qedge[i].to; if (vis[v]) { qedge[i].lca = find(v); if (i % 2) { qedge[i + 1].lca = qedge[i].lca; } else { qedge[i - 1].lca = qedge[i].lca; } } } } intwork() { cin >> n >> m >> s; for (int i = 1, x, y; i < n; ++i) { cin >> x >> y; add(x, y); add(y, x); } for (int i = 1, x, y; i <= m; ++i) { cin >> x >> y; qadd(x, y); qadd(y, x); } Tarjan(s); for (int i = 1; i <= m; ++i) { cout << qedge[i << 1].lca << '\n'; } return0; } }
namespace SHAWN { constint N = 2e5 + 7;// 双向边开二倍空间 int head[N], cnt; structedge{ int to, next; }edge[N]; int dfn[N], low[N]; bool used[N], flag[N]; int n, m, res, tim;
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; }
voidTarjan(int u, int fa){ used[u] = true; low[u] = dfn[u] = ++tim; int child = 0; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!used[v]) { if (fa == u) { ++child; } Tarjan(v, u); // 如果v是u的孩子 low[u] = min(low[u], low[v]); // 如果u不是根且low[u] >= dfn[u]就是割点 if (fa != u && low[v] >= dfn[u] && !flag[u]) { flag[u] = true; ++res; } } // 如果(u,v)是一条回边 elseif (fa != v) { low[u] = min(low[u], dfn[v]); } } // 如果u是根且有两个或两个以上子树就是割点 if (fa == u && child >= 2 && !flag[u]) { flag[u] = true; ++res; } }
intwork() { cin >> n >> m; for (int i = 1, x, y; i <= m; ++i) { cin >> x >> y; add(x, y); add(y, x); } // 不保证连通所以要多次跑 for (int i = 1; i <= n; ++i) { if (!used[i]) { tim = 0; Tarjan(i, i); } } cout << res << '\n'; for (int i = 1; i <= n; ++i) { if (flag[i]) { cout << i << ' '; } } return0; } }
namespace SHAWN { constint N = 1e4 + 7; int head[N], cnt; structedge { int to, next; }edge[N]; structnode { int a, b; }; int dfn[N], low[N]; int n, m, tim; structcmp{ booloperator()(const node &x, const node &y)const{ if (x.a != y.a) { return x.a > y.a; } else { return x.b > y.b; } } }; priority_queue<node, vector<node>, cmp> q;
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; }
voidTarjan(int u, int fa){ low[u] = dfn[u] = ++tim; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!dfn[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) { q.push({u,v}); } } elseif (dfn[v] < dfn[u] && v != fa) { low[u] = min(low[u], dfn[v]); } } }
intwork() { cin >> n >> m; for (int i = 1, x, y; i <= m; ++i) { cin >> x >> y; add(x, y); add(y, x); } for (int i = 1; i <= n; ++i) { if (!dfn[i]) { Tarjan(i, i); } } while (!q.empty()) { auto it = q.top(); q.pop(); cout << it.a << ' ' << it.b << '\n'; } return0; } }
namespace SHAWN { constint N = 1e6 + 7; int head[N], cnt; structedge { int to, next; }edge[N]; int n, tim, x, y; int dfn[N], low[N]; bool vis[N], flag[N];
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; }
voidTarjan(int u, int fa){ low[u] = dfn[u] = ++tim; vis[u] = true; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!vis[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); // 这里多加一个u!=x和dfn[y]>=dfn[v]的特判就OK了 if (fa != u && low[v] >= dfn[u] && u != x && dfn[y] >= dfn[v]) { flag[u] = true; } } elseif (fa != v) { low[u] = min(low[u], dfn[v]); } } }
intwork() { cin >> n; while (cin >> x >> y && x && y) { add(x, y); add(y, x); } cin >> x >> y; Tarjan(x, x); for (int i = 1; i <= n; ++i) { if (flag[i]) { cout << i << '\n'; return0; } } cout << "No solution\n"; return0; } }
namespace SHAWN { constint N = 2e6 + 7; // 请注意这里一定要开二倍空间,要不然会寄 int head[N], cnt; structedge { int to, next; }edge[N]; int n, m, a, b, tim, res; int dfn[N], low[N], acnt[N], bcnt[N], par[N]; // acnt[i]表示i结点子树中A类点数量,bcnt同理 // par用来记每个结点在dfs生成树中的父亲 bool flag[N];
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; }
voidTarjan(int u, int fa){ low[u] = dfn[u] = ++tim; par[u] = fa; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!dfn[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) { if (!acnt[v] || !bcnt[v] || acnt[v] == a || bcnt[v] == b) { // A类或B类有一个为0或全满就说明符合要求 flag[v] = true; ++res; } } acnt[u] += acnt[v]; bcnt[u] += bcnt[v]; // 从下向上递归统计子树情况 } elseif (dfn[v] < dfn[u] && fa != v) { low[u] = min(low[u], dfn[v]); } } } intwork() { cin >> n >> m >> a >> b; for (int i = 1, x; i <= a; ++i) { cin >> x; acnt[x] = 1; } for (int i = 1, x; i <= b; ++i) { cin >> x; bcnt[x] = 1; } // 最开始每个点的子树就是自己 for (int i = 1, x, y; i <= m; ++i) { cin >> x >> y; add(x, y); add(y, x); } Tarjan(1, 0); cout << res << '\n'; for (int i = 1; i <= n; ++i) { if (flag[i]) { cout << i << ' ' << par[i] << '\n'; } } return0; } }
namespace SHAWN { constint N = 1e5 + 10; int head[N], cnt; structedge { int to, next; }edge[N]; int n, m, tim, top, idx; int dfn[N], low[N], st[N], size[N], scc[N]; bool chkin[N];
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; }
voidTarjan(int u){ low[u] = dfn[u] = ++tim; st[++top] = u;// 搜到就入栈 chkin[u] = true; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!dfn[v]) { Tarjan(v); low[u] = min(low[u], low[v]); } elseif (chkin[v]) { low[u] = min(low[u], dfn[v]); } } if (low[u] == dfn[u]) { //low[u]=dfn[u]时弹栈直到自己 int v; ++idx; do { v = st[top--]; scc[v] = idx; chkin[v] = false; ++size[idx]; } while (v != u); } } intwork() { cin >> n >> m; for (int i = 1, x, y; i <= m; ++i) { cin >> x >> y; add(x, y); } for (int i = 1; i <= n; ++i) { if (!dfn[i]) { Tarjan(i); } } int ans = 0; for (int i = 1; i <= idx; ++i) { ans += (size[i] > 1); } cout << ans << '\n'; for (int i = 1; i <= n; ++i) { cout << scc[i] << ' '; } return0; } }
namespace SHAWN { constint N = 5e4 + 7; int head[N], cnt; structedge { int to, next; }edge[N]; int n, m, tim, top, idx, cont, ans; int dfn[N], low[N], size[N], sta[N], scc[N], diag[N]; bool chkin[N];
inlinevoidadd(int u, int v){ edge[++cnt].next = head[u]; edge[cnt].to = v; head[u] = cnt; }
voidTarjan(int u){ low[u] = dfn[u] = ++tim; sta[++top] = u; chkin[u] = true; for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].to; if (!dfn[v]) { Tarjan(v); low[u] = min(low[u], low[v]); } elseif (chkin[v]) { low[u] = min(low[u], dfn[v]); } } if (low[u] == dfn[u]) { int v; ++idx; do { v = sta[top--]; scc[v] = idx; chkin[v] = false; ++size[idx]; } while (v != u); } }
intwork() { cin >> n >> m; for (int i = 1, x, y; i <= m; ++i) { cin >> x >> y; add(x, y); } for (int i = 1; i <= n; ++i) { if (!dfn[i]) { Tarjan(i); } } for (int i = 1; i <= n; ++i) { for (int j = head[i]; j; j = edge[j].next) { int v = edge[j].to; if (scc[i] != scc[v]) { ++diag[scc[i]]; } } } for (int i = 1; i <= idx; ++i) { if (!diag[i]) { ++cont; ans += size[i]; } } if (cont == 1) { cout << ans << '\n'; } else { cout << "0\n"; } return0; } }