//parent為並查集,FIND為並查集的查找操作 2 Tarjan(u) 3 visit[u] = true 4 for each (u, v) in QUERY 5 if visit[v] 6 ans(u, v) = FIND(v) 7 for each (u, v) in TREE 8 if !visit[v] 9 Tarjan(v) 10 parent[v] = u下面的博客關於Tarjin算法解釋的比較清楚。 http://hi.baidu.com/billdu/item/9938ed34ab9416352e20c41f
/* Tarjin 離線算法 struct node { int x, d; }; int n, m, dis[maxn], ans[maxn], vis[maxn] = {0}, f[maxn]; vectorV[maxn], query[maxn]; void init() { scanf("%d%d", &n, &m); int a, b; char ch; node tmp; for (int i = 0; i < m; i++) { scanf("%d%d%d %c", &a, &b, &tmp.d, &ch); tmp.x = b; V[a].push_back(tmp); tmp.x = a; V[b].push_back(tmp); } scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d%d", &a, &b); tmp.d = i, tmp.x = b; query[a].push_back(tmp); tmp.x = a; query[b].push_back(tmp); } } int find(int x) { if (f[x] != x) f[x] = find(f[x]); return f[x]; } void dfs(int u, int d) { vis[u] = 1, f[u] = u, dis[u] = d; for (int i = 0; i < query[u].size(); i++) if (vis[query[u][i].x]) { int v = query[u][i].x, w = query[u][i].d; ans[w] = dis[u] + dis[v] - 2 * dis[find(v)]; } for (int i = 0; i < V[u].size(); i++) if (!vis[V[u][i].x]) { int v = V[u][i].x, w = V[u][i].d; dfs(v, d + w); f[v] = u; } } int main () { init(); dfs(1, 0); for (int i = 0; i < m; i++) printf("%d\n", ans[i]); return 0; } */
//DFS + RMQ 在線算法 struct node { int x, d; }; vectorV[maxn]; int E[maxn * 2], D[maxn * 2], first[maxn], vis[maxn], dis[maxn], n, m, top = 1; int dp[30][maxn * 2]; void init() { scanf("%d%d", &n, &m); int a, b; char ch; node tmp; for (int i = 0; i < m; i++) { scanf("%d%d%d %c", &a, &b, &tmp.d, &ch); tmp.x = b; V[a].push_back(tmp); tmp.x = a; V[b].push_back(tmp); } } void dfs(int u, int dep, int w) { vis[u] = 1, E[top] = u, D[top] = dep, first[u] = top++, dis[u] = w; for (int i = 0; i < V[u].size(); i++) if (!vis[V[u][i].x]) { int v = V[u][i].x, cost = V[u][i].d; dfs(v, dep + 1, w + cost); E[top] = u, D[top++] = dep; } } void ST(int num) { for (int i = 1; i <= num; i++) dp[0][i] = i; for (int i = 1; i <= log2(num); i++) for (int j = 1; j <= num; j++) if (j + (1 << i) - 1 <= num) { int a = dp[i - 1][j], b = dp[i - 1][j + (1 << i >> 1)]; if (D[a] < D[b]) dp[i][j] = a; else dp[i][j] = b; } } int RMQ(int x, int y) { int k = (int) log2(y - x + 1.0); int a = dp[k][x], b = dp[k][y - (1 << k) + 1]; if (D[a] < D[b]) return a; return b; } int main () { init(); dfs(1, 0, 0); ST(top - 1); scanf("%d", &m); int x, y; while(m--) { scanf("%d%d", &x, &y); int a = first[x], b = first[y]; if (a > b) swap(a, b); int pos = RMQ(a, b); printf("%d\n", dis[x] + dis[y] - 2 * dis[E[pos]]); } return 0; }