//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 离线算法
struct node
{
int x, d;
};
int n, m, dis[maxn], ans[maxn], vis[maxn] = {0}, f[maxn];
vector<node> V[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;
};
vector<node> V[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;
}Linux鲜为人知的安全漏洞:不要将输出内容管道给你的shell
原文:http://blog.csdn.net/lanxuezaipiao/article/details/19119973