解题思路:Tarjan离线处理
一篇介绍LCA的很好的博客:http://www.cppblog.com/menjitianya/archive/2015/12/10/212447.html
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10005;
struct Edge
{
int k,next,cost;
}edge[maxn<<1];
struct Ask
{
int k,next,id;
}ask[maxn<<1];
int n,m,c,cnt1,cnt2,pre[maxn],head[maxn];
int color[maxn],ans[maxn],dis[maxn],fa[maxn];
bool vis[maxn];
int find(int x)
{
if(fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
void addedge(int u,int v,int cost)
{
edge[cnt1].k = v;
edge[cnt1].cost = cost;
edge[cnt1].next = pre[u];
pre[u] = cnt1++;
}
void addask(int u,int v,int id)
{
ask[cnt2].id = id;
ask[cnt2].k = v;
ask[cnt2].next = head[u];
head[u] = cnt2++;
}
void Tarjan(int u,int root,int len)
{
vis[u] = true;
fa[u] = u;
dis[u] = len;
for(int i = pre[u]; i != -1; i = edge[i].next)
{
int v = edge[i].k;
if(vis[v]) continue;
Tarjan(v,root,len + edge[i].cost);
fa[v] = u;
}
color[u] = root;
for(int i = head[u]; i != -1; i = ask[i].next)
{
int v = ask[i].k;
if(color[v] == root)
{
int ancestor = find(v);
ans[ask[i].id] = dis[u] + dis[v] - 2*dis[ancestor];
}
}
}
int main()
{
int u,v,cost;
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
memset(pre,-1,sizeof(pre));
memset(head,-1,sizeof(head));
cnt1 = cnt2 = 0;
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&u,&v,&cost);
addedge(u,v,cost);
addedge(v,u,cost);
}
for(int i = 1; i <= c; i++)
{
scanf("%d%d",&u,&v);
addask(u,v,i);
addask(v,u,i);
}
memset(vis,false,sizeof(vis));
memset(color,0,sizeof(color));
memset(ans,-1,sizeof(ans));
for(int i = 1; i <= n; i++)
if(vis[i] == false)
Tarjan(i,i,0);
for(int i = 1; i <= c; i++)
{
if(ans[i] == -1)
printf("Not connected\n");
else printf("%d\n",ans[i]);
}
}
return 0;
}