P2783 有机化学之神偶尔会做作弊
我觉得我对的一比可就是wa三个点我决定不改了毕竟我已经领会到精髓了
(还有这种人?????
就是tarjan缩点+倍增求lca
因为是无向图, 要判断一下, dfs的时候不能返回上一个点, 否则全图就是一整个强连通分量了qwq
1 #include<cmath> 2 #include<cstdio> 3 #include<iostream> 4 using namespace std; 5 const int maxn = 10010, maxm = 50050; 6 int n, m, q, log2n, num = 0, cot = 0, top = 0, tim = 0; 7 int head[maxm], hear[maxm], dep[maxn], sd[maxn], jump[maxn][23], sta[maxn], low[maxn], dfn[maxn], x[maxm], y[maxm]; 8 bool vis[maxn]; 9 struct edg { 10 int nxt, to; 11 }e[maxm << 1], edge[maxm << 1]; 12 void add(int from, int to) { 13 e[++num].to = to; 14 e[num].nxt = head[from]; 15 head[from] = num; 16 } 17 void readd(int from, int to) { 18 edge[++cot].to = to; 19 edge[cot].nxt = hear[from]; 20 hear[from] = cot; 21 } 22 void tarjan(int u, int fa) { 23 low[u] = dfn[u] = ++tim; 24 sta[++top] = u; 25 vis[u] = 1; 26 for(int i = head[u]; i; i = e[i].nxt) { 27 int v = e[i].to; 28 if(v != fa) { 29 if(!dfn[v]) 30 { 31 tarjan(v, u); 32 low[u] = min(low[u], low[v]); 33 } 34 else if(vis[v]) low[u] = min(low[u], dfn[v]); 35 } 36 } 37 if(dfn[u] == low[u]) { 38 int y; 39 while(y = sta[top--]) { 40 sd[y] = u; 41 vis[y] = 0; 42 if(y == u) break; 43 } 44 } 45 } 46 void dfs(int x) { 47 for(int i = hear[x]; i; i = edge[i].nxt) 48 { 49 int y = edge[i].to; 50 if(y != jump[x][0]) 51 { 52 dep[y] = dep[x] + 1; 53 jump[y][0] = x; 54 dfs(y); 55 } 56 } 57 } 58 void init() { 59 for(int i = 1; i <= log2n; i++) 60 for(int j = 1; j <= n; j++) 61 jump[j][i] = jump[jump[j][i-1]][i-1]; 62 } 63 int LCA(int x, int y) { 64 if(dep[x] < dep[y]) swap(x, y); 65 int t = dep[x] - dep[y]; 66 for(int i = 0; (1<<i) <= n; i++) 67 if(t & (1<<i)) x = jump[x][i]; 68 if(x == y) return x; 69 for(int i = log2n; i >= 0; i--) { 70 if(jump[x][i] != jump[y][i]) { 71 x = jump[x][i]; 72 y = jump[y][i]; 73 } 74 } 75 return jump[x][0]; 76 } 77 void print(int ans) { 78 if (!ans) return; 79 print(ans >> 1); 80 printf("%d", ans & 1); 81 } 82 int main() { 83 scanf("%d%d", &n, &m); 84 log2n = log(n) / log(2) + 1; 85 for(int i = 1; i <= m; i++) { 86 int u, v; 87 scanf("%d%d", &x[i], &y[i]); 88 add(x[i], y[i]), add(y[i], x[i]); 89 } 90 for(int i = 1; i <= n; i++) 91 if(!dfn[i]) tarjan(i, i); 92 for(int i = 1; i <= m; i++) { 93 if(sd[x[i]] != sd[y[i]]){ 94 readd(sd[x[i]], sd[y[i]]), readd(sd[y[i]], sd[x[i]]); 95 } 96 } 97 jump[1][0] = 0; 98 dep[1] = 1; 99 dfs(1); 100 init(); 101 scanf("%d", &q); 102 for(int i = 1; i <= q; i++) { 103 int u, v; 104 scanf("%d%d", &u, &v); 105 int lca = LCA(u, v); 106 int ans = dep[u] + dep[v] - 2*dep[lca] + 1; 107 print(ans); 108 printf(" "); 109 } 110 return 0; 111 }