Navigation Nightmare POJ - 1984
思路:先把线路存储下来,题目没有明说询问的时间是非递减的,实测是非递减的,如果不是就有点麻烦了。设置两个距离数组,分别存储水平方向和竖直方向上点距根结点的距离,设置北为正南为负,西为负东为正(这里随心所欲)
具体代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
const int N = 40010;
struct Node{
int a, b, c;
char op;
}node[N];
int n, m, k;
int p[N], d1[N], d2[N];//d1存储水平距离,d2存储竖直距离
int find(int x){
if(p[x] != x){
int t = find(p[x]);
d1[x] += d1[p[x]];
d2[x] += d2[p[x]];
p[x] = t;
}
return p[x];
}
int main(){
scanf("%d%d", &n, &m);
for(int i=1; i<=n; ++i){
p[i] = i;
d1[i] = d2[i] = 0;
}
for(int i=0; i<m; ++i){
int a, b, c;
char op[2];
scanf("%d%d%d%s", &a, &b, &c, op);
node[i] = {a, b, c, *op};
}
scanf("%d", &k);
int i = 0;
while(k--){
int x, y, s;
scanf("%d%d%d", &x, &y, &s);
while(i < s){
int a = node[i].a, b = node[i].b, c = node[i].c;
char op = node[i].op;
int pa = find(a), pb = find(b);
if(a != b){
p[pa] = pb;
if(op == 'N' || op == 'S'){
if(op == 'S') c = -c;
d2[pa] = c + d2[b] - d2[a];
d1[pa] = d1[b] - d1[a];
}else{
if(op == 'W') c = -c;
d1[pa] = c + d1[b] - d1[a];
d2[pa] = d2[b] - d2[a];
}
}
++i;
}
int px = find(x), py = find(y);
int xx = abs(d1[y] - d1[x]) + abs(d2[y] - d2[x]);
if(px != py) puts("-1");
else printf("%d\n", xx);
}
return 0;
}