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;}


原创粉丝点击