带边权的LCA,记录Dis[x]为根到x的距离,有dis[x,y]=dis[x]+dis[y]-2*dis[lca(x,y)]。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=44000;
struct node
{
int w,v,next;
}edge[maxn<<1],q[maxn<<1];
int g[maxn],gg[maxn];
int ideg[maxn];
int dis[maxn];
bool vis[maxn];
int fa[maxn];
int res[maxn][3];
int n,m,k;
int find(int x)
{
if (x!=fa[x]) return fa[x]=find(fa[x]);
return x;
}
void tarjan(int u)
{
vis[u]=1;
fa[u]=u;
int v;
for (int j=gg[u]; j!=-1; j=q[j].next)
{
v=q[j].v;
if (vis[v])
{
res[q[j].w][2]=find(v);
}
}
for (int j=g[u]; j!=-1; j=edge[j].next)
{
v=edge[j].v;
if (!vis[v])
{
dis[v]=dis[u]+edge[j].w;
tarjan(v);
fa[v]=u;
}
}
}
int en,eq;
int main()
{
// freopen("in.txt","r",stdin);
while (~scanf("%d%d",&n,&m))
{
en=eq=0;
memset(g,-1,sizeof g);
memset(gg,-1,sizeof gg);
memset(vis,false,sizeof vis);
memset(dis,0,sizeof dis);
memset(ideg,0,sizeof ideg);
memset(res,0,sizeof res);
int x,y,z;
char ttt[4];
for (int i=1; i<=m; i++)
{
scanf("%d%d%d",&x,&y,&z);
scanf("%s",ttt);
edge[en].v=y;
edge[en].w=z;
edge[en].next=g[x];
g[x]=en;
en++;
edge[en].v=x;
edge[en].w=z;
edge[en].next=g[y];
g[y]=en;
en++;
}
scanf("%d",&k);
for (int i=1; i<=k; i++)
{
scanf("%d%d",&x,&y);
q[eq].v=y;
q[eq].w=i;
q[eq].next=gg[x];
gg[x]=eq;
eq++;
q[eq].v=x;
q[eq].w=i;
q[eq].next=gg[y];
gg[y]=eq;
eq++;
res[i][0]=x;
res[i][1]=y;
}
dis[0]=0;
tarjan(1);
for (int i=1; i<=k; i++)
cout<<dis[res[i][0]]+dis[res[i][1]]-(dis[res[i][2]]<<1)<<endl;
}
return 0;
}