原题链接:http://poj.org/problem?id=1986
题意:n个点,最大40000,m条连边,保证无环,任何两点可达,连边后面的那个字母可以无视,不需处理。接下来k行查询。
分析:就是一道模板题,没啥说的,注意查询可能 1 1 ,2 2这样的数据,输出就是0,注意一下就行。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#define INF 99999999
#define eps 0.0001
#define N ((1<<12)+10)
using namespace std;
struct Edge
{
int v;
int w;
int next;
};
struct Query
{
int v;
int index;
int next;
};
int n, m, k;
int cnt;
int q_cnt;
Edge edge[80005];
Query query[20005];
int z[40005];
int head[40005];
int q_head[40005];
int dis[40005];
int pre[40005];
bool vis[40005];
void init()
{
q_cnt = 0;
cnt = 0;
memset(vis, 0, sizeof(vis));
memset(z, -1, sizeof(z));//赋值-1
memset(dis, 0, sizeof(dis));
memset(head, -1, sizeof(head));
memset(q_head, -1, sizeof(q_head));
memset(pre, 0, sizeof(pre));
}
void add(int u, int v, int w)
{
edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt++;
edge[cnt].v = u; edge[cnt].w = w; edge[cnt].next = head[v]; head[v] = cnt++;
}
void q_add(int u, int v, int index)
{
query[q_cnt].v = v; query[q_cnt].index = index; query[q_cnt].next = q_head[u]; q_head[u] = q_cnt++;
query[q_cnt].v = u; query[q_cnt].index = index; query[q_cnt].next = q_head[v]; q_head[v] = q_cnt++;
}
int find(int x)
{
if (x == pre[x])
return x;
return pre[x] = find(pre[x]);
}
void tarjan(int u)
{
pre[u] = u;
vis[u] = 1;
for (int i = q_head[u]; i != -1; i = query[i].next)
{
int v = query[i].v;
if (vis[v])
z[query[i].index] = dis[u] + dis[v] - 2 * dis[find(v)];
}
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if (!vis[v])
{
dis[v] = dis[u] + edge[i].w;
tarjan(v);
pre[v] = u;
}
}
}
int main()
{
int u, v, w;
char s[3];
while (~scanf("%d%d", &n, &m))
{
init();
for (int i = 0; i < m; i++)
{
scanf("%d%d%d%s", &u, &v, &w, s);
add(u, v, w);
}
scanf("%d", &k);
for (int i = 0; i < k; i++)
{
scanf("%d%d", &u, &v);
q_add(u, v, i);
}
tarjan(1);
for (int i = 0; i < k; i++)
printf("%d\n", z[i]);
}
return 0;
}