1 条题解
-
0
发现必经路口是 任意一条简单路径上的割点。因为每一条路径上的割点都一样,所有直接求 简单路径并上的割点。
建圆方树,答案即为圆方树 简单路径上除 和 外的圆点。
时间复杂度 。
#include <bits/stdc++.h> using namespace std; namespace Milkcat { typedef long long LL; const int N = 1e6 + 5; struct edge { int to, next; } e[N << 1]; LL n, m, u, v, tot, edge_cnt, cnt, a[N], siz[N], dfn[N], low[N], head[N]; bool qwq, cut[N << 1], vis[N]; vector<int> G[N], ans; stack<int> s; void add(int u, int v) { e[++ edge_cnt].to = v; e[edge_cnt].next = head[u]; head[u] = edge_cnt; } void Add(int u, int v) { G[u].push_back(v), G[v].push_back(u); } void tarjan(int u) { int last = 0; dfn[u] = low[u] = ++ tot, s.push(u); for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (!dfn[v]) { tarjan(v), low[u] = min(low[u], low[v]); if (low[v] >= dfn[u]) { Add(++ cnt, u), a[cnt] = 1; while (!s.empty() && last != v) Add(cnt, last = s.top()), a[cnt] ++, s.pop(); } } low[u] = min(low[u], dfn[v]); } } void dfs(int u, int fa) { if (u == n) { qwq = 1; return; } for (int v : G[u]) { if (v != fa) dfs(v, u); if (qwq) { if (u != 1 && a[u] == -1) ans.push_back(u); return; } } } int main() { cin >> n >> m, edge_cnt = 1, cnt = n; for (int i = 1; i <= m; i ++) cin >> u >> v, add(u, v), add(v, u); for (int i = 1; i <= n; i ++) a[i] = -1; tarjan(1), dfs(1, 0); sort(ans.begin(), ans.end()); cout << ans.size() << '\n'; for (int v : ans) cout << v << ' '; return 0; } } int main() { return Milkcat::main(); }
- 1
信息
- ID
- 420
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 19
- 已通过
- 14
- 上传者