|
思路: 每次新增点a -> b的时候,union (b, a),节点中保存的是距离的偏移量。 查询a, b的关系的时候,如果a, b不是一类,就输出-1,如果是的话,就将a,b的偏移量相加然后输出。
#include <stdio.h>

 struct node {
int a, b;
struct node *next;
};

struct node nodes[10032];

 struct {
int from, to, len;
char dir;
struct node *query;
} arr[40032];

 struct {
int parent, x, y;
} set[400032];

int N, M;

__inline int abs(int i)
  {
return i > 0 ? i : -i;
}

int set_find(int i)
  {
int r, p;

p = set[i].parent;
if (!p)
return i;
r = set_find(p);
set[i].x += set[p].x;
set[i].y += set[p].y;
set[i].parent = r;
return r;
}

void set_union(int from, int to, int x, int y)
  {
int r = set_find(to);
set[r].parent = from;
set[r].x = x - set[to].x;
set[r].y = y - set[to].y;
}

int main()
  {
int i, j, k, ia, ib, x, y;
char str[16];
struct node *t, **pt;

freopen("e:\\test\\in.txt", "r", stdin);

scanf("%d%d", &N, &M);
 for (i = 1; i <= M; i++) {
scanf("%d%d%d%s", &arr[i].from, &arr[i].to, &arr[i].len, str);
arr[i].dir = str[0];
}
scanf("%d", &k);
 for (i = 0; i < k; i++) {
scanf("%d%d%d", &nodes[i].a, &nodes[i].b, &j);
for (pt = &arr[j].query; *pt; pt = &(*pt)->next);
*pt = &nodes[i];
}
 for (i = 1; i <= M; i++) {
 switch (arr[i].dir) {
case 'E': x = arr[i].len; y = 0; break;
case 'W': x = -arr[i].len; y = 0; break;
case 'N': x = 0; y = arr[i].len; break;
case 'S': x = 0; y = -arr[i].len; break;
}
set_union(arr[i].from, arr[i].to, x, y);
 for (t = arr[i].query; t; t = t->next) {
ia = set_find(t->a);
ib = set_find(t->b);
if (ia != ib)
j = -1;
else
j = abs(set[t->a].x - set[t->b].x) + abs(set[t->a].y - set[t->b].y);
printf("%d\n", j);
}
}

return 0;
}


|