任意门:http://poj.org/problem?id=1984

Navigation Nightmare

Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 7783   Accepted: 2801
Case Time Limit: 1000MS

Description

Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series of M (1 <= M < 40,000) vertical and horizontal roads each of varying lengths (1 <= length <= 1000) connect the farms. A map of these farms might look something like the illustration below in which farms are labeled F1..F7 for clarity and lengths between connected farms are shown as (n):

           F1 --- (13) ---- F6 --- (9) ----- F3
            |                                 |
           (3)                                |
            |                                (7)
           F4 --- (20) -------- F2            |
            |                                 |
           (2)                               F5
            |
           F7 

Being an ASCII diagram, it is not precisely to scale, of course.

Each farm can connect directly to at most four other farms via roads that lead exactly north, south, east, and/or west. Moreover, farms are only located at the endpoints of roads, and some farm can be found at every endpoint of every road. No two roads cross, and precisely one path 
(sequence of roads) links every pair of farms.

FJ lost his paper copy of the farm map and he wants to reconstruct it from backup information on his computer. This data contains lines like the following, one for every road:

There is a road of length 10 running north from Farm #23 to Farm #17 
There is a road of length 7 running east from Farm #1 to Farm #17 
...

As FJ is retrieving this data, he is occasionally interrupted by questions such as the following that he receives from his navigationally-challenged neighbor, farmer Bob:

What is the Manhattan distance between farms #1 and #23?

FJ answers Bob, when he can (sometimes he doesn't yet have enough data yet). In the example above, the answer would be 17, since Bob wants to know the "Manhattan" distance between the pair of farms. 
The Manhattan distance between two points (x1,y1) and (x2,y2) is just |x1-x2| + |y1-y2| (which is the distance a taxicab in a large city must travel over city streets in a perfect grid to connect two x,y points).

When Bob asks about a particular pair of farms, FJ might not yet have enough information to deduce the distance between them; in this case, FJ apologizes profusely and replies with "-1".

Input

* Line 1: Two space-separated integers: N and M

* Lines 2..M+1: Each line contains four space-separated entities, F1,
        F2, L, and D that describe a road. F1 and F2 are numbers of
        two farms connected by a road, L is its length, and D is a
        character that is either 'N', 'E', 'S', or 'W' giving the
        direction of the road from F1 to F2.

* Line M+2: A single integer, K (1 <= K <= 10,000), the number of FB's
        queries

* Lines M+3..M+K+2: Each line corresponds to a query from Farmer Bob
        and contains three space-separated integers: F1, F2, and I. F1
        and F2 are numbers of the two farms in the query and I is the
        index (1 <= I <= M) in the data after which Bob asks the
        query. Data index 1 is on line 2 of the input data, and so on.

Output

* Lines 1..K: One integer per line, the response to each of Bob's
        queries.  Each line should contain either a distance
        measurement or -1, if it is impossible to determine the
        appropriate distance.

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6 1
1 4 3
2 6 6

Sample Output

13
-1
10

Hint

At time 1, FJ knows the distance between 1 and 6 is 13. 
At time 3, the distance between 1 and 4 is still unknown. 
At the end, location 6 is 3 units west and 7 north of 2, so the distance is 10. 

​题意概括:

给出 M 个建树的操作,K 次查询,每次查询 x 到 y 经过前 num 次建树操作的距离,如果未联通则输出-1;

解题思路:

带权并查集,路径压缩采用向量法。

dx【i】表示 i 距离所在树根结点的横坐标

dy【i】表示 i 距离所在树根结点的纵坐标

合并 u v 过程:

先合并两棵子树

ru = getfa(u)

rv = getfa(v)

改变其中一棵子树的根结点

fa[ rv ] = ru;

更新根结点的相对值(之后子树的相对值会通过查找父结点的过程进行更新)

dx[ rv ] = dx[ u ] - dx[ v ] - wx[ u, v];

dy[ rv ] = dy[ u ] - dy[ v ] - wy[ u, v];

先执行num次建树操作

查找父结点的同时压缩路径

查询最后结果

如果相同根,直接计算两点的曼哈顿距离

否则不连通

Tip:

题目没有说查询的 num 是非递减有序的,所以处理查询前要对 num 进行排序!!!

也就是说离线处理,在线处理会出错。(虽然poj上的数据我没有排序也AC了, 但这是需要考虑的情况)

AC code:

 1 //离线带权并查集
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cstring>
 6 #define INF 0x3f3f3f3f
 7 using namespace std;
 8 const int MAXN = 4e4+5;
 9 const int MAXK = 1e4+10;
10 struct Query{int x, y, index, no;}q[MAXN];  //查询信息
11 int fa[MAXN], dx[MAXN], dy[MAXN];   //并查集,路径压缩(距离起点的横坐标距离 和 纵坐标距离)
12 int u[MAXN], v[MAXN];               //第i个操作的起点 和 终点
13 int ans[MAXK];    //第 k 次查询的结果
14 int wx[MAXN], wy[MAXN];             //wx[ i ] 第i个操作的横坐标边权 wy[ i ] 第i个操作的纵坐标边权
15 int N, M, K;
16
17 void init()
18 {
19     for(int i = 0; i <= N; i++){
20         fa[i] = i;
21         dx[i] = 0;
22         dy[i] = 0;
23     }
24     memset(q, 0, sizeof(q));
25 }
26 int aabs(int x){return x>0?x:-x;}
27 int getfa(int s)
28 {
29     if(s == fa[s]) return s;
30     int t = fa[s];
31     fa[s] = getfa(fa[s]);    //压缩路径
32     dx[s] += dx[t];
33     dy[s] += dy[t];
34     return fa[s];
35 }
36 bool cmp(Query q1,Query q2){return q1.index < q2.index;}
37 int main()
38 {
39     while(~scanf("%d%d", &N, &M)){
40         //scanf("%d%d", &N, &M);
41         init();
42         char nod;
43         for(int i = 1, d; i <= M; i++){
44             scanf("%d%d%d %c", &u[i], &v[i], &d, &nod);
45             if(nod == 'E') {wx[i] = d; wy[i] = 0;}
46             else if(nod == 'W') {wx[i] = -d; wy[i] = 0;}
47             else if(nod == 'N') {wy[i] = d; wx[i] = 0;}
48             else if(nod == 'S') {wy[i] = -d; wx[i] = 0;}
49         }
50         scanf("%d", &K);
51         for(int i = 1; i <= K; i++){
52             scanf("%d%d%d", &q[i].x, &q[i].y, &q[i].index);
53             q[i].no = i;
54         }
55         sort(q+1, q+K+1, cmp);
56         int k = 1;
57         for(int i = 1; i <= K; i++){
58             //printf("i:%d\n", i);
59             while(k <= q[i].index){                 //合并index个操作
60                 //printf("k:%d\n", k);
61                 int ru = getfa(u[k]);
62                 int rv = getfa(v[k]);
63                 //printf("u:%d ru:%d v:%d rv:%d\n", u[k], ru, v[k], rv);
64                 fa[rv] = ru;                            //合并两个集合
65                 dx[rv] = dx[u[k]] - dx[v[k]] - wx[k];   //
66                 dy[rv] = dy[u[k]] - dy[v[k]] - wy[k];
67                 k++;
68                 }
69             //printf("k:%d\n", k);
70             if(getfa(q[i].x) != getfa(q[i].y)) ans[q[i].no] = -1;  //两点经过index次操作后还是没有相连
71             else{
72                 ans[q[i].no] = aabs(dx[q[i].x] - dx[q[i].y]) + aabs(dy[q[i].x] - dy[q[i].y]);
73             }
74             //puts("");
75         }
76         for(int it = 1; it <= K; it++) printf("%d\n", ans[it]);
77     }
78     return 0;
79 }

View Code

一道拖了好久好久的带权并查集,给几个数据纪念一下

  1 Input:
  2 8 7
  3 1 2 1 S
  4 3 4 5 S
  5 5 6 8 S
  6 7 8 2 S
  7 3 2 3 N
  8 7 6 13 N
  9 5 4 7 N
 10 6
 11 1 3 1
 12 1 4 5
 13 3 4 2
 14 4 5 7
 15 1 8 6
 16 1 8 7
 17
 18 Output:
 19 -1
 20 9
 21 5
 22 7
 23 -1
 24 39
 25
 26 Input:
 27 100 99
 28 1 2 1000 E
 29 2 3 1000 E
 30 3 4 1000 E
 31 4 5 1000 E
 32 5 6 1000 E
 33 6 7 1000 E
 34 7 8 1000 E
 35 8 9 1000 E
 36 9 10 1000 E
 37 10 11 1000 E
 38 11 12 1000 E
 39 12 13 1000 E
 40 13 14 1000 E
 41 14 15 1000 E
 42 15 16 1000 E
 43 16 17 1000 E
 44 17 18 1000 E
 45 18 19 1000 E
 46 19 20 1000 E
 47 20 21 1000 E
 48 21 22 1000 E
 49 22 23 1000 E
 50 23 24 1000 E
 51 24 25 1000 E
 52 26 27 1000 E
 53 27 28 1000 E
 54 28 29 1000 E
 55 29 30 1000 E
 56 30 31 1000 E
 57 31 32 1000 E
 58 32 33 1000 E
 59 33 34 1000 E
 60 34 35 1000 E
 61 35 36 1000 E
 62 36 37 1000 E
 63 37 38 1000 E
 64 38 39 1000 E
 65 39 40 1000 E
 66 40 41 1000 E
 67 41 42 1000 E
 68 42 43 1000 E
 69 43 44 1000 E
 70 44 45 1000 E
 71 45 46 1000 E
 72 46 47 1000 E
 73 47 48 1000 E
 74 48 49 1000 E
 75 49 50 1000 E
 76 51 52 1000 E
 77 52 53 1000 E
 78 53 54 1000 E
 79 54 55 1000 E
 80 55 56 1000 E
 81 56 57 1000 E
 82 57 58 1000 E
 83 58 59 1000 E
 84 59 60 1000 E
 85 60 61 1000 E
 86 61 62 1000 E
 87 62 63 1000 E
 88 63 64 1000 E
 89 64 65 1000 E
 90 65 66 1000 E
 91 66 67 1000 E
 92 67 68 1000 E
 93 68 69 1000 E
 94 69 70 1000 E
 95 70 71 1000 E
 96 71 72 1000 E
 97 72 73 1000 E
 98 73 74 1000 E
 99 74 75 1000 E
100 76 77 1000 E
101 77 78 1000 E
102 78 79 1000 E
103 79 80 1000 E
104 80 81 1000 E
105 81 82 1000 E
106 82 83 1000 E
107 83 84 1000 E
108 84 85 1000 E
109 85 86 1000 E
110 86 87 1000 E
111 87 88 1000 E
112 88 89 1000 E
113 89 90 1000 E
114 90 91 1000 E
115 91 92 1000 E
116 92 93 1000 E
117 93 94 1000 E
118 94 95 1000 E
119 95 96 1000 E
120 96 97 1000 E
121 97 98 1000 E
122 98 99 1000 E
123 99 100 1000 E
124 10 40 100 S
125 30 60 100 S
126 70 90 100 S
127 100
128 34 44 96
129 55 65 96
130 38 48 96
131 63 73 96
132 2 12 96
133 76 86 96
134 1 11 96
135 62 72 96
136 8 18 96
137 41 51 96
138 58 68 96
139 60 70 96
140 30 40 96
141 67 77 96
142 60 70 96
143 74 84 96
144 80 90 96
145 11 21 96
146 21 31 96
147 87 97 96
148 33 43 96
149 20 30 96
150 83 93 96
151 35 45 96
152 56 66 96
153 32 42 96
154 44 54 96
155 36 46 96
156 69 79 96
157 74 84 96
158 51 61 96
159 64 74 96
160 38 48 96
161 89 99 96
162 37 47 96
163 40 50 96
164 36 46 96
165 89 99 96
166 11 21 96
167 5 15 96
168 39 49 96
169 30 40 96
170 64 74 96
171 30 40 96
172 58 68 96
173 33 43 96
174 14 24 96
175 10 20 96
176 43 53 96
177 86 96 96
178 6 16 96
179 37 47 96
180 67 77 96
181 51 61 96
182 33 43 96
183 32 42 96
184 82 92 96
185 77 87 96
186 30 40 96
187 60 70 96
188 22 32 96
189 80 90 96
190 34 44 96
191 60 70 96
192 40 50 96
193 32 42 96
194 61 71 96
195 75 85 96
196 82 92 96
197 33 43 96
198 80 90 96
199 83 93 96
200 25 35 96
201 15 25 96
202 22 32 96
203 44 54 96
204 48 58 96
205 35 45 96
206 53 63 96
207 52 62 96
208 82 92 96
209 59 69 96
210 51 61 96
211 59 69 96
212 71 81 96
213 83 93 96
214 90 100 96
215 62 72 96
216 31 41 96
217 29 39 96
218 84 94 96
219 53 63 96
220 71 81 96
221 79 89 96
222 22 32 96
223 20 30 96
224 72 82 96
225 44 54 96
226 5 15 96
227 63 73 96
228
229 Output:
230 10000
231 10000
232 10000
233 10000
234 10000
235 10000
236 10000
237 10000
238 10000
239 -1
240 10000
241 10000
242 10000
243 -1
244 10000
245 -1
246 10000
247 10000
248 -1
249 10000
250 10000
251 -1
252 10000
253 10000
254 10000
255 10000
256 -1
257 10000
258 -1
259 -1
260 10000
261 10000
262 10000
263 10000
264 10000
265 10000
266 10000
267 10000
268 10000
269 10000
270 10000
271 10000
272 10000
273 10000
274 10000
275 10000
276 10000
277 10000
278 -1
279 10000
280 10000
281 10000
282 -1
283 10000
284 10000
285 10000
286 10000
287 10000
288 10000
289 10000
290 -1
291 10000
292 10000
293 10000
294 10000
295 10000
296 10000
297 -1
298 10000
299 10000
300 10000
301 10000
302 -1
303 10000
304 -1
305 -1
306 -1
307 10000
308 10000
309 10000
310 10000
311 10000
312 10000
313 10000
314 -1
315 10000
316 10000
317 10000
318 10000
319 10000
320 10000
321 10000
322 -1
323 10000
324 -1
325 -1
326 -1
327 -1
328 10000
329 10000

text

小蒟蒻不才,如有错误,欢迎大佬们指正~

POJ 1984 Navigation Nightmare 【经典带权并查集】相关推荐

  1. POJ:1182 食物链(带权并查集)

    http://poj.org/problem?id=1182 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1 ...

  2. POJ 1733 Parity game(带权并查集)

    题目链接:http://poj.org/problem?id=1733 题目大意:给你m条信息,每条信息告诉你区间l~r的1的个数是奇数还是偶数,如果后面出现信息跟前面矛盾则这条信息是错误的,问在第一 ...

  3. 带权并查集【bzoj3362】: [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    [bzoj]3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 ​ 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂 ...

  4. BZOJ 3362 Navigation Nightmare 带权并查集

    题目大意:给定一些点之间的位置关系,求两个点之间的曼哈顿距离 此题土豪题.只是POJ也有一道相同的题,能够刷一下 别被题目坑到了,这题不强制在线.把询问离线处理就可以 然后就是带权并查集的问题了.. ...

  5. 【POJ - 1703】Find them, Catch them(带权并查集之--种类并查集 权为与父节点关系)

    题干: Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36176   Accep ...

  6. POJ 1182 食物链 [并查集 带权并查集 开拓思路]

    传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit  ...

  7. How Many Answers Are Wrong HDU - 3038(带权并查集经典题,满满的都是注释)

    How Many Answers Are Wrong HDU - 3038  点击打开链接 题意:现在有n个数(你并不知道这n个数是什么),m次查询,每次查询给出u,v,w.表示从第u个数到第v个数的 ...

  8. POJ 2492 A Bug's Life 带权并查集

    题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...

  9. POJ 2912 Rochambeau(难,好题,枚举+带权并查集)

    下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...

最新文章

  1. 学习 spring-boot (一)
  2. shell学习(4)- awk
  3. android 之DatePicker以及TimePicker的用法
  4. ROS学习笔记-ROS语音识别与语音输出[2]
  5. 前端学习(3289):object.define2
  6. mysql group by 规则_mysql 的group by 满足的规则要求:
  7. vue-cli 使用better-scroll
  8. 根据分类id找出父类id
  9. 使用nginx作为代理实现动静分离
  10. STL源码剖析(三)
  11. 非线性动力学 matlab,非线性动力学matlab
  12. leetcode 左程云笔记
  13. php语言简述_PHP语言的简介
  14. 手机无线网络为啥无法连接服务器,手机wifi打不开及手机WiFi连接上但不能上网,怎么办?...
  15. 2022年中职组网络安全国赛AB模块解析第一套
  16. MarkdownNote
  17. CF1400:1490E、448B、1462FD、650A、1380B、1451C
  18. Java程序员校招蚂蚁金服,微信抢红包实战案例,纯干货
  19. UE4+手柄对应按键测试
  20. 全球与中国远程摄像机市场深度研究分析报告

热门文章

  1. Bq769XX IIC 通讯 ALERT引脚
  2. 硬皮病 中医疗法大全
  3. Python金融大数据分析:用pandas处理金融时间序列数据的基础知识
  4. 如何设置网站顶部的logo图标
  5. 【ROS学习记录】2021/7/2 Gazebo+rviz仿真(一)
  6. asp.net毕业设计家电维修保养信息系统
  7. 快手短视频如何支撑 10 亿月活,揭秘快手大数据中台架构!
  8. pwn - 格式化字符串攻击
  9. DL289西雅图-上海成功回国记录(2021-06-25)
  10. vue 孙子组件获取祖先组件数据