POJ 1986 Distance Queries [LCA]


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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章