(带权并查集理解不通的我觉得可以用这题磨练一下)
重点:用dx[], dy[]去维护各个点的坐标的值
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 100010;
struct node
{
int a, b, l;
char d;
}s[N];
struct nodee
{
int a, b, I, rank, ans; // rank记录原先的位置
}q[N];
int p[N], dx[N], dy[N];
int n, m, k;
bool cmp(nodee x, nodee y)
{
return x.I < y.I;
}
bool cmpp(nodee x, nodee y) // 用于还原输出顺序
{
return x.rank < y.rank;
}
void init()
{
for (int i = 0; i < N; i ++)
p[i] = i;
}
int find(int x)
{
if (x != p[x])
{
int t = find(p[x]);
dx[x] += dx[p[x]];
dy[x] += dy[p[x]];
p[x] = t;
}
return p[x];
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
init();
cin >> n >> m;
for (int i = 1; i <= m; i ++)
{
int a, b, l;
char d;
cin >> a >> b >> l >> d;
s[i] = {a, b, l, d};
}
cin >> k;
for (int i = 1; i <= k; i ++)
{
int a, b, I;
cin >> a >> b >> I;
q[i] = {a, b, I, i};
}
sort(q + 1, q + k + 1, cmp);
int idx = 1;
for (int i = 1; i <= m; i ++)
{
int a = s[i].a, b = s[i].b, l = s[i].l;
char ch = s[i].d;
int fa = find(a), fb = find(b);
if (fa != fb)
{
p[fa] = fb;
if (ch == 'E') dx[fa] = dx[b] - dx[a] - l, dy[fa] = dy[b] - dy[a]; // 这里调了两小时,也可能脑子真的混乱了。
else if (ch == 'W') dx[fa] = dx[b] - dx[a] + l, dy[fa] = dy[b] - dy[a];
else if (ch == 'N') dy[fa] = dy[b] - dy[a] - l, dx[fa] = dx[b] - dx[a];
else dy[fa] = dy[b] - dy[a] + l, dx[fa] = dx[b] - dx[a];
}
while (idx <= k && i == q[idx].I) // 到哪个点存哪个值
{
int a = q[idx].a, b = q[idx].b;
int fa = find(a), fb = find(b);
if (fa != fb) q[idx].ans = -1;
else q[idx].ans = abs(dx[a] - dx[b]) + abs(dy[a] - dy[b]);
idx ++;
}
}
sort(q + 1, q + k + 1, cmpp); // 记得将顺序返回(输出要求)
for (int i = 1; i <= k; i ++) cout << q[i].ans << '\n';
return 0;
}