ContestHunter#24-C 逃不掉的路
Description:
求无向图的必经边
思路:一眼题 将无向图缩成树,然后求两点树上距离
#include<iostream> #include<vector> #include<cstring> using namespace std; const int N = 2e5 + 10; int head[N], now = 1; struct edges{ int to, next; }edge[N<<1]; void add(int u,int v){ edge[++now] = {v, head[u]}; head[u] = now;} int n, m, dfn[N], low[N], cnt, tot, dict[N], Q, ans[N], dis[N], fa[N], vis[N]; bool bri[N<<1]; struct query{ int to, id; }; vector<query> q[N]; void q_add(int u, int v, int y){ q[u].push_back({v, y}); q[v].push_back({u, y}); } void tarjan(int x, int in_edge){ dfn[x] = low[x] = ++cnt; for(int i = head[x]; i; i = edge[i].next){ int v = edge[i].to; if(!dfn[v]){ tarjan(v, i); low[x] = min(low[x], low[v]); if(low[v] > dfn[x]) bri[i] = bri[i ^ 1] = 1; } else if(i != (in_edge ^ 1)) low[x] = min(low[x], dfn[v]); } } void dfs(int x){ dict[x] = tot; vis[x] = 1; for(int i = head[x]; i; i = edge[i].next){ int v = edge[i].to; if(vis[v] || bri[i]) continue; dfs(v); } } int get(int x){ if(x != fa[x]) return fa[x] = get(fa[x]); return x; } void LCA(int x){ vis[x] = 1; for(int i = head[x]; i; i = edge[i].next){ int v = edge[i].to; if(vis[v]) continue; dis[v] = dis[x] + 1; LCA(v); fa[v] = x; } for(int i = 0; i < q[x].size(); i++){ int v = q[x][i].to, id = q[x][i].id; if(vis[v] == 2){ int lca = get(v); ans[id] = min(ans[id], dis[x] + dis[v] - 2 * dis[lca]); } } vis[x] = 2; } struct input{ int x, y; }in[N]; int main(){ scanf("%d%d", &n, &m); int x, y; for(int i = 1; i <= m; i++){ scanf("%d%d", &x, &y); in[i] = {x, y}; add(x, y); add(y, x); } for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i, 0); for(int i = 1; i <= n; i++) if(!vis[i]) tot++, dfs(i); memset(head, 0, sizeof(head)); memset(edge, 0, sizeof(edge)); now = 0; memset(vis, 0, sizeof(vis)); for(int i = 1; i <= m; i++){ x = dict[in[i].x], y = dict[in[i].y]; if(x == y) continue; add(x, y), add(y, x); } scanf("%d", &Q); for(int i = 1; i <= Q; i++){ scanf("%d%d", &x, &y); x = dict[x], y = dict[y]; if(x == y) ans[i] = 0; else{ q_add(x, y, i); ans[i] = 1e9; } } for(int i = 1; i <= n; i++) fa[i] = i; LCA(1); for(int i = 1; i <= Q; i++) printf("%d\n", ans[i]); return 0; }