给出一个图,求两点的曼哈顿距离(|det(x)|+|det(y)|)。题目本身不难,用并查集记录集合及两点间的关系,可我不得不说这题给出数据的方式相当坑爹,硬是把一个在线的问题搞成离线的,就好像活生生把一个直男掰弯一样。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 40010
 6 #define M 10005
 7 int fa[N];
 8 int X[26],Y[26];
 9 struct Dir{
10     int x,y;
11 }dir[N];
12 struct Road{
13     int u,v,x,y;
14 }road[N];
15 struct Query{
16     int u,v,id,ans;
17 }qry[M];
18 int r[M];
19 bool cmp(int a,int b){
20     return qry[a].id<qry[b].id;
21 }
22 int find(int s){
23     if(fa[s] == s)
24     {
25         dir[s].x=dir[s].y=0;
26         return s;
27     }
28     int t = fa[s];
29     fa[s] = find(t);
30     dir[s].x += dir[t].x;
31     dir[s].y += dir[t].y;
32     return fa[s];
33 }
34 void comb(int n)
35 {
36     int s,t;
37     Road m;
38     m = road[n];
39     s = find(m.u);
40     t = find(m.v);
41     if(s == t) return ;
42     fa[t] = s;
43     dir[t].x = dir[m.u].x+m.x-dir[m.v].x;
44     dir[t].y = dir[m.u].y+m.y-dir[m.v].y;
45 }
46 inline int cal(int a,int b){
47     return abs(dir[a].x-dir[b].x)+abs(dir[a].y-dir[b].y);
48 }
49 int main()
50 {
51     int m,n,k,l,i,j;
52     char ch;
53     Y['N'-'A']=1;
54     Y['S'-'A']=-1;
55     X['W'-'A']=-1;
56     X['E'-'A']=1;
57     scanf("%d%d",&n,&m);
58     for(i = 1; i <= m; i++)
59     {
60         fa[i]=i;
61         scanf("%d%d%d %c",&road[i].u,&road[i].v,&l,&ch);
62         road[i].x = l*X[ch-'A'];
63         road[i].y = l*Y[ch-'A'];
64     }
65     scanf("%d",&k);
66     for(i = 1; i <= k; i++)
67     {
68         r[i] = i;
69         scanf("%d%d%d",&qry[i].u,&qry[i].v,&qry[i].id);
70     }
71     sort(r,r+k,cmp);
72     for(i = j = 1; i <= k; i++)
73     {
74         Query &t = qry[r[i]];
75         for(;j <= t.id; j++) comb(j);
76         if(find(t.u)!=find(t.v))
77             t.ans = -1;
78         else t.ans = cal(t.u,t.v);
79     }
80     for(i = 1; i <= k; i++) printf("%d\n",qry[i].ans);
81     return 0;
82 }