您的位置:首页 > 产品设计 > UI/UE

POJ 1986 Distance Queries [LCA]

2012-05-26 16:28 363 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: