zoukankan      html  css  js  c++  java
  • 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

    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
    ", 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 }
    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
    小蒟蒻不才,如有错误,欢迎大佬们指正~
  • 相关阅读:
    寒假day08
    操作系统(一)操作系统的目标和作用
    数据结构排序算法稳定性总结——写给自己看
    网络请求生命周期
    PHP 不同类型之间的松散和严格比较
    php配置可被设定范围
    laravel5.7 前后端分离开发 实现基于API请求的token认证
    laravel 自动加载 自定义的文件/辅助函数
    laravel5.7 migrate 时报错 Specified key was too long error 解决方案
    PHP 命名空间
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9780359.html
Copyright © 2011-2022 走看看