根据带权并查集常用的和向量计算差不多的套路进行路径压缩和区间合并
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 50000
using namespace std;
int XX[maxn],fa[maxn],YY[maxn];
struct link{
int a,c,b;
char s[5];
}link[maxn];
struct query{
int a,b,c;
}q[maxn];
int getFa(int i)
{
if(i==fa[i])return i;
int pre = fa[i];
fa[i] = getFa(fa[i]);
XX[i] = XX[i]+XX[pre];
YY[i] = YY[i]+YY[pre];
return fa[i];
}
int main()
{
int n,m1,m2;
scanf("%d%d",&n,&m1);
for(int i=1;i<=n;i++){fa[i] = i,XX[i] = 0,YY[i] = 0;}
for(int i=1;i<=m1;i++)scanf("%d %d %d %s",&link[i].a,&link[i].b,&link[i].c,link[i].s);
scanf("%d",&m2);
for(int i=1;i<=m2;i++)scanf("%d %d %d",&q[i].a,&q[i].b,&q[i].c);
int pre=1;
for(int i=1;i<=m1;i++)
{
int preX = 0,preY = 0;
if(link[i].s[0]=='N')preY+=link[i].c;
else if(link[i].s[0]=='S')preY-=link[i].c;
else if(link[i].s[0]=='W')preX-=link[i].c;
else preX+=link[i].c;
int faa = getFa(link[i].a);
int fab = getFa(link[i].b);
if(faa!=fab)
{
fa[fab] = faa;
XX[fab] = XX[link[i].a]+preX-XX[link[i].b];
YY[fab] = YY[link[i].a]+preY-YY[link[i].b];
}
while(q[pre].c==i&&pre<=m2)
{
int faa = getFa(q[pre].a);
int fab = getFa(q[pre].b);
if(faa!=fab)printf("-1\n");
else printf("%d\n",abs(XX[q[pre].a]-XX[q[pre].b])+abs(YY[q[pre].a]-YY[q[pre].b]));
pre++;
}
}
return 0;
}