gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Merge bugfix #197
0 1 0
merge 1.0
0 files changed with 4 insertions and 7 deletions:
↑ Collapse diff ↑
Ignore white space 256 line context
... ...
@@ -1052,337 +1052,334 @@
1052 1052
      if (id < 0) {
1053 1053
        return -1;
1054 1054
      }
1055 1055
      id = nodes[id].next;
1056 1056
      while (depth--) {
1057 1057
        id = nodes[id].left;
1058 1058
      }
1059 1059
      return id;
1060 1060
    }
1061 1061

	
1062 1062

	
1063 1063
    void setPrio(int id) {
1064 1064
      int jd = nodes[id].left;
1065 1065
      nodes[id].prio = nodes[jd].prio;
1066 1066
      nodes[id].item = nodes[jd].item;
1067 1067
      jd = nodes[jd].next;
1068 1068
      while (jd != -1) {
1069 1069
        if (comp(nodes[jd].prio, nodes[id].prio)) {
1070 1070
          nodes[id].prio = nodes[jd].prio;
1071 1071
          nodes[id].item = nodes[jd].item;
1072 1072
        }
1073 1073
        jd = nodes[jd].next;
1074 1074
      }
1075 1075
    }
1076 1076

	
1077 1077
    void push(int id, int jd) {
1078 1078
      nodes[id].size = 1;
1079 1079
      nodes[id].left = nodes[id].right = jd;
1080 1080
      nodes[jd].next = nodes[jd].prev = -1;
1081 1081
      nodes[jd].parent = id;
1082 1082
    }
1083 1083

	
1084 1084
    void pushAfter(int id, int jd) {
1085 1085
      int kd = nodes[id].parent;
1086 1086
      if (nodes[id].next != -1) {
1087 1087
        nodes[nodes[id].next].prev = jd;
1088 1088
        if (kd >= 0) {
1089 1089
          nodes[kd].size += 1;
1090 1090
        }
1091 1091
      } else {
1092 1092
        if (kd >= 0) {
1093 1093
          nodes[kd].right = jd;
1094 1094
          nodes[kd].size += 1;
1095 1095
        }
1096 1096
      }
1097 1097
      nodes[jd].next = nodes[id].next;
1098 1098
      nodes[jd].prev = id;
1099 1099
      nodes[id].next = jd;
1100 1100
      nodes[jd].parent = kd;
1101 1101
    }
1102 1102

	
1103 1103
    void pushRight(int id, int jd) {
1104 1104
      nodes[id].size += 1;
1105 1105
      nodes[jd].prev = nodes[id].right;
1106 1106
      nodes[jd].next = -1;
1107 1107
      nodes[nodes[id].right].next = jd;
1108 1108
      nodes[id].right = jd;
1109 1109
      nodes[jd].parent = id;
1110 1110
    }
1111 1111

	
1112 1112
    void popRight(int id) {
1113 1113
      nodes[id].size -= 1;
1114 1114
      int jd = nodes[id].right;
1115 1115
      nodes[nodes[jd].prev].next = -1;
1116 1116
      nodes[id].right = nodes[jd].prev;
1117 1117
    }
1118 1118

	
1119 1119
    void splice(int id, int jd) {
1120 1120
      nodes[id].size += nodes[jd].size;
1121 1121
      nodes[nodes[id].right].next = nodes[jd].left;
1122 1122
      nodes[nodes[jd].left].prev = nodes[id].right;
1123 1123
      int kd = nodes[jd].left;
1124 1124
      while (kd != -1) {
1125 1125
        nodes[kd].parent = id;
1126 1126
        kd = nodes[kd].next;
1127 1127
      }
1128 1128
      nodes[id].right = nodes[jd].right;
1129 1129
    }
1130 1130

	
1131 1131
    void split(int id, int jd) {
1132 1132
      int kd = nodes[id].parent;
1133 1133
      nodes[kd].right = nodes[id].prev;
1134 1134
      nodes[nodes[id].prev].next = -1;
1135 1135

	
1136 1136
      nodes[jd].left = id;
1137 1137
      nodes[id].prev = -1;
1138 1138
      int num = 0;
1139 1139
      while (id != -1) {
1140 1140
        nodes[id].parent = jd;
1141 1141
        nodes[jd].right = id;
1142 1142
        id = nodes[id].next;
1143 1143
        ++num;
1144 1144
      }
1145 1145
      nodes[kd].size -= num;
1146 1146
      nodes[jd].size = num;
1147 1147
    }
1148 1148

	
1149 1149
    void pushLeft(int id, int jd) {
1150 1150
      nodes[id].size += 1;
1151 1151
      nodes[jd].next = nodes[id].left;
1152 1152
      nodes[jd].prev = -1;
1153 1153
      nodes[nodes[id].left].prev = jd;
1154 1154
      nodes[id].left = jd;
1155 1155
      nodes[jd].parent = id;
1156 1156
    }
1157 1157

	
1158 1158
    void popLeft(int id) {
1159 1159
      nodes[id].size -= 1;
1160 1160
      int jd = nodes[id].left;
1161 1161
      nodes[nodes[jd].next].prev = -1;
1162 1162
      nodes[id].left = nodes[jd].next;
1163 1163
    }
1164 1164

	
1165 1165
    void repairLeft(int id) {
1166 1166
      int jd = ~(classes[id].parent);
1167 1167
      while (nodes[jd].left != -1) {
1168 1168
        int kd = nodes[jd].left;
1169 1169
        if (nodes[jd].size == 1) {
1170 1170
          if (nodes[jd].parent < 0) {
1171 1171
            classes[id].parent = ~kd;
1172 1172
            classes[id].depth -= 1;
1173 1173
            nodes[kd].parent = ~id;
1174 1174
            deleteNode(jd);
1175 1175
            jd = kd;
1176 1176
          } else {
1177 1177
            int pd = nodes[jd].parent;
1178 1178
            if (nodes[nodes[jd].next].size < cmax) {
1179 1179
              pushLeft(nodes[jd].next, nodes[jd].left);
1180
              if (nodes[jd].item == nodes[pd].item) {
1180
              if (less(jd, nodes[jd].next) ||
1181
                  nodes[jd].item == nodes[pd].item) {
1181 1182
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1182 1183
                nodes[nodes[jd].next].item = nodes[jd].item;
1183 1184
              }
1184 1185
              popLeft(pd);
1185 1186
              deleteNode(jd);
1186 1187
              jd = pd;
1187 1188
            } else {
1188 1189
              int ld = nodes[nodes[jd].next].left;
1189 1190
              popLeft(nodes[jd].next);
1190 1191
              pushRight(jd, ld);
1191 1192
              if (less(ld, nodes[jd].left) || 
1192 1193
                  nodes[ld].item == nodes[pd].item) {
1193 1194
                nodes[jd].item = nodes[ld].item;
1194 1195
                nodes[jd].prio = nodes[ld].prio;
1195 1196
              }
1196 1197
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1197 1198
                setPrio(nodes[jd].next);
1198 1199
              }
1199 1200
              jd = nodes[jd].left;
1200 1201
            }
1201 1202
          }
1202 1203
        } else {
1203 1204
          jd = nodes[jd].left;
1204 1205
        }
1205 1206
      }
1206 1207
    }
1207 1208

	
1208 1209
    void repairRight(int id) {
1209 1210
      int jd = ~(classes[id].parent);
1210 1211
      while (nodes[jd].right != -1) {
1211 1212
        int kd = nodes[jd].right;
1212 1213
        if (nodes[jd].size == 1) {
1213 1214
          if (nodes[jd].parent < 0) {
1214 1215
            classes[id].parent = ~kd;
1215 1216
            classes[id].depth -= 1;
1216 1217
            nodes[kd].parent = ~id;
1217 1218
            deleteNode(jd);
1218 1219
            jd = kd;
1219 1220
          } else {
1220 1221
            int pd = nodes[jd].parent;
1221 1222
            if (nodes[nodes[jd].prev].size < cmax) {
1222 1223
              pushRight(nodes[jd].prev, nodes[jd].right);
1223
              if (nodes[jd].item == nodes[pd].item) {
1224
              if (less(jd, nodes[jd].prev) ||
1225
                  nodes[jd].item == nodes[pd].item) {
1224 1226
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1225 1227
                nodes[nodes[jd].prev].item = nodes[jd].item;
1226 1228
              }
1227 1229
              popRight(pd);
1228 1230
              deleteNode(jd);
1229 1231
              jd = pd;
1230 1232
            } else {
1231 1233
              int ld = nodes[nodes[jd].prev].right;
1232 1234
              popRight(nodes[jd].prev);
1233 1235
              pushLeft(jd, ld);
1234 1236
              if (less(ld, nodes[jd].right) ||
1235 1237
                  nodes[ld].item == nodes[pd].item) {
1236 1238
                nodes[jd].item = nodes[ld].item;
1237 1239
                nodes[jd].prio = nodes[ld].prio;
1238 1240
              }
1239 1241
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1240 1242
                setPrio(nodes[jd].prev);
1241 1243
              }
1242 1244
              jd = nodes[jd].right;
1243 1245
            }
1244 1246
          }
1245 1247
        } else {
1246 1248
          jd = nodes[jd].right;
1247 1249
        }
1248 1250
      }
1249 1251
    }
1250 1252

	
1251 1253

	
1252 1254
    bool less(int id, int jd) const {
1253 1255
      return comp(nodes[id].prio, nodes[jd].prio);
1254 1256
    }
1255 1257

	
1256
    bool equal(int id, int jd) const {
1257
      return !less(id, jd) && !less(jd, id);
1258
    }
1259

	
1260

	
1261 1258
  public:
1262 1259

	
1263 1260
    /// \brief Returns true when the given class is alive.
1264 1261
    ///
1265 1262
    /// Returns true when the given class is alive, ie. the class is
1266 1263
    /// not nested into other class.
1267 1264
    bool alive(int cls) const {
1268 1265
      return classes[cls].parent < 0;
1269 1266
    }
1270 1267

	
1271 1268
    /// \brief Returns true when the given class is trivial.
1272 1269
    ///
1273 1270
    /// Returns true when the given class is trivial, ie. the class
1274 1271
    /// contains just one item directly.
1275 1272
    bool trivial(int cls) const {
1276 1273
      return classes[cls].left == -1;
1277 1274
    }
1278 1275

	
1279 1276
    /// \brief Constructs the union-find.
1280 1277
    ///
1281 1278
    /// Constructs the union-find.
1282 1279
    /// \brief _index The index map of the union-find. The data
1283 1280
    /// structure uses internally for store references.
1284 1281
    HeapUnionFind(ItemIntMap& _index)
1285 1282
      : index(_index), first_class(-1),
1286 1283
        first_free_class(-1), first_free_node(-1) {}
1287 1284

	
1288 1285
    /// \brief Insert a new node into a new component.
1289 1286
    ///
1290 1287
    /// Insert a new node into a new component.
1291 1288
    /// \param item The item of the new node.
1292 1289
    /// \param prio The priority of the new node.
1293 1290
    /// \return The class id of the one-item-heap.
1294 1291
    int insert(const Item& item, const Value& prio) {
1295 1292
      int id = newNode();
1296 1293
      nodes[id].item = item;
1297 1294
      nodes[id].prio = prio;
1298 1295
      nodes[id].size = 0;
1299 1296

	
1300 1297
      nodes[id].prev = -1;
1301 1298
      nodes[id].next = -1;
1302 1299

	
1303 1300
      nodes[id].left = -1;
1304 1301
      nodes[id].right = -1;
1305 1302

	
1306 1303
      nodes[id].item = item;
1307 1304
      index[item] = id;
1308 1305

	
1309 1306
      int class_id = newClass();
1310 1307
      classes[class_id].parent = ~id;
1311 1308
      classes[class_id].depth = 0;
1312 1309

	
1313 1310
      classes[class_id].left = -1;
1314 1311
      classes[class_id].right = -1;
1315 1312

	
1316 1313
      if (first_class != -1) {
1317 1314
        classes[first_class].prev = class_id;
1318 1315
      }
1319 1316
      classes[class_id].next = first_class;
1320 1317
      classes[class_id].prev = -1;
1321 1318
      first_class = class_id;
1322 1319

	
1323 1320
      nodes[id].parent = ~class_id;
1324 1321

	
1325 1322
      return class_id;
1326 1323
    }
1327 1324

	
1328 1325
    /// \brief The class of the item.
1329 1326
    ///
1330 1327
    /// \return The alive class id of the item, which is not nested into
1331 1328
    /// other classes.
1332 1329
    ///
1333 1330
    /// The time complexity is O(log(n)).
1334 1331
    int find(const Item& item) const {
1335 1332
      return findClass(index[item]);
1336 1333
    }
1337 1334

	
1338 1335
    /// \brief Joins the classes.
1339 1336
    ///
1340 1337
    /// The current function joins the given classes. The parameter is
1341 1338
    /// an STL range which should be contains valid class ids. The
1342 1339
    /// time complexity is O(log(n)*k) where n is the overall number
1343 1340
    /// of the joined nodes and k is the number of classes.
1344 1341
    /// \return The class of the joined classes.
1345 1342
    /// \pre The range should contain at least two class ids.
1346 1343
    template <typename Iterator>
1347 1344
    int join(Iterator begin, Iterator end) {
1348 1345
      std::vector<int> cs;
1349 1346
      for (Iterator it = begin; it != end; ++it) {
1350 1347
        cs.push_back(*it);
1351 1348
      }
1352 1349

	
1353 1350
      int class_id = newClass();
1354 1351
      { // creation union-find
1355 1352

	
1356 1353
        if (first_class != -1) {
1357 1354
          classes[first_class].prev = class_id;
1358 1355
        }
1359 1356
        classes[class_id].next = first_class;
1360 1357
        classes[class_id].prev = -1;
1361 1358
        first_class = class_id;
1362 1359

	
1363 1360
        classes[class_id].depth = classes[cs[0]].depth;
1364 1361
        classes[class_id].parent = classes[cs[0]].parent;
1365 1362
        nodes[~(classes[class_id].parent)].parent = ~class_id;
1366 1363

	
1367 1364
        int l = cs[0];
1368 1365

	
1369 1366
        classes[class_id].left = l;
1370 1367
        classes[class_id].right = l;
1371 1368

	
1372 1369
        if (classes[l].next != -1) {
1373 1370
          classes[classes[l].next].prev = classes[l].prev;
1374 1371
        }
1375 1372
        classes[classes[l].prev].next = classes[l].next;
1376 1373

	
1377 1374
        classes[l].prev = -1;
1378 1375
        classes[l].next = -1;
1379 1376

	
1380 1377
        classes[l].depth = leftNode(l);
1381 1378
        classes[l].parent = class_id;
1382 1379

	
1383 1380
      }
1384 1381

	
1385 1382
      { // merging of heap
1386 1383
        int l = class_id;
1387 1384
        for (int ci = 1; ci < int(cs.size()); ++ci) {
1388 1385
          int r = cs[ci];
0 comments (0 inline)