POJ 1984 Navigation Nightmare 经典带权并查集
Posted ymzjj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1984 Navigation Nightmare 经典带权并查集相关的知识,希望对你有一定的参考价值。
任意门:http://poj.org/problem?id=1984
Navigation Nightmare
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 7783 | Accepted: 2801 | |
Case Time Limit: 1000MS |
Description
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 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 ", i); 59 while(k <= q[i].index){ //合并index个操作 60 //printf("k:%d ", k); 61 int ru = getfa(u[k]); 62 int rv = getfa(v[k]); 63 //printf("u:%d ru:%d v:%d rv:%d ", 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 ", 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 ", ans[it]); 77 } 78 return 0; 79 }
一道拖了好久好久的带权并查集,给几个数据纪念一下
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
以上是关于POJ 1984 Navigation Nightmare 经典带权并查集的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1984 Navigation Nightmare 经典带权并查集
Navigation Nightmare POJ - 1984 (带权并查集)
POJ 1984Navigation Nightmare(带权并查集)