POJ 1986 Distance Queries [LCA]
来源:互联网 发布:淘宝淘宝军军用口粮 编辑:程序博客网 时间:2024/05/18 11:50
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 40010;const int maxk = 10010;int n, m, k;int cnt1, cnt2;int head1[maxn], head2[maxn];int set[maxn], an[maxn];int dist[maxn], ans[maxk];bool vis[maxn], flag[maxn];struct edge_node{ int v; int dis; int next;}edge1[maxn<<1];struct query_node{ int v; int id; int next;}edge2[maxk<<1];void addEdge1(int u, int v, int dis){ edge1[cnt1].v = v; edge1[cnt1].dis = dis; edge1[cnt1].next = head1[u]; head1[u] = cnt1++;}void addEdge2(int u, int v, int id){ edge2[cnt2].v = v; edge2[cnt2].id = id; edge2[cnt2].next = head2[u]; head2[u] = cnt2++;}int find(int x){ if (x != set[x]) set[x] = find(set[x]); return set[x];}void Union(int x, int y){ x = find(x); y = find(y); set[x] = y;}void tarjan(int u, int dis){ dist[u] = dis; an[u] = u; set[u] = u; vis[u] = true; for (int i = head1[u]; i != -1; i = edge1[i].next) { if (!vis[edge1[i].v]) { tarjan(edge1[i].v, dis + edge1[i].dis); Union(u, edge1[i].v); an[find(u)] = u; } } flag[u] = true; for (int i = head2[u]; i != -1; i = edge2[i].next) { if (flag[edge2[i].v]) ans[edge2[i].id] = dist[u] + dist[edge2[i].v] - 2 * dist[an[find(edge2[i].v)]]; }}void init(){ memset(vis, false, sizeof(vis)); memset(flag, false, sizeof(flag)); memset(head1, -1, sizeof(head1)); memset(head2, -1, sizeof(head2)); cnt1 = cnt2 = 0;}int main(){ while (scanf("%d %d", &n, &m) != EOF) { int u, v, len; char dir[2]; init(); for (int i = 0; i < m; ++i) { scanf("%d%d%d%s", &u, &v, &len, dir); addEdge1(u, v, len); addEdge1(v, u, len); } scanf("%d", &k); for (int i = 0; i < k; ++i) { scanf("%d%d", &u, &v); addEdge2(u, v, i); addEdge2(v, u, i); } tarjan(1, 0); for (int i = 0; i < k; ++i) printf("%d\n", ans[i]); } return 0;}