1 条题解

  • 0
    @ 2023-4-5 10:54:03

    发现必经路口是 1n1\to n 任意一条简单路径上的割点。因为每一条路径上的割点都一样,所有直接求 1n1\to n 简单路径并上的割点。

    建圆方树,答案即为圆方树 1n1\to n 简单路径上除 11nn 外的圆点。

    时间复杂度 O(n+e)\mathcal{O}(n+e)

    #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
    上传者