leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

power_grid_maintenance.c (3340B)


// 3607. Power Grid Maintenance
#include "leetcode.h"

/*
 * you are given an integer 'c' representing power stations, each with a unique
 * identifier 'id' from 1 to 'c'. these stations are interconnected via 'n'
 * bidirectional cables, represented by a 2 array 'connections' where each
 * element 'connections[i] = [u_i, v_i]' indicates a connection between station
 * 'u_i' and 'v_i'. stations that are directly or indirectly connected form a
 * power grid. initially, all stations are online (operational). you are also
 * given a 2d integer array 'quries' where each query is one of the following
 * types: '[1, x]': a maintenance check is requested for station 'x'. if station
 * 'x' is online, it resolves the check by itself. if station 'x' is offline,
 * the check is resolved by the operational station with the smallest 'id' in
 * the same power grid as 'x'. if no operational station exists in that grid,
 * return -1. '[2, x]': station 'x' goes offline. return an array of integers
 * representing the results of each query of type '[1, x]' in the order they
 * appear.
 */

int find(int *parent, int x) {
  if (parent[x] != x)
    parent[x] = find(parent, parent[x]);
  return parent[x];
}

int *processQueries(int c, int **connections, int connectionsSize,
                    int *connectionsColSize, int **queries, int queriesSize,
                    int *queriesColSize, int *returnSize) {
  int *parent = (int *)malloc((c + 1) * sizeof(int));
  for (int i = 0; i <= c; i++)
    parent[i] = i;
  for (int i = 0; i < connectionsSize; i++) {
    int a = connections[i][0], b = connections[i][1];
    int aa = find(parent, a), bb = find(parent, b);
    if (aa != bb)
      parent[bb] = aa;
  }
  int *next_node = (int *)calloc(c + 1, sizeof(int));
  int *cmp_min = (int *)calloc(c + 1, sizeof(int));
  int *prev = (int *)calloc(c + 1, sizeof(int));
  for (int i = 1; i <= c; i++) {
    int r = find(parent, i);
    if (!cmp_min[r])
      cmp_min[r] = i;
    else
      next_node[prev[r]] = i;
    prev[r] = i;
  }
  int *offline = (int *)calloc(c + 1, sizeof(int)), ri = 0;
  int *ans = (int *)malloc(queriesSize * sizeof(int));
  for (int i = 0; i < queriesSize; i++) {
    int t = queries[i][0], x = queries[i][1], r = find(parent, x);
    if (t == 1) {
      if (!offline[x])
        ans[ri++] = x;
      else
        ans[ri++] = cmp_min[r] ? cmp_min[r] : -1;
    } else {
      if (offline[x])
        continue;
      offline[x] = 1;
      if (cmp_min[r] == x) {
        int y = next_node[x];
        while (y && offline[y])
          y = next_node[y];
        cmp_min[r] = y;
      }
    }
  }
  free(parent);
  free(next_node);
  free(cmp_min);
  free(prev);
  free(offline);
  *returnSize = ri;
  return ans;
}

int main() {
  int c1i[4][2] = {{1, 2}, {2, 3}, {3, 4}, {4, 5}},
      q1i[5][2] = {{1, 3}, {2, 1}, {1, 1}, {2, 2}, {1, 2}};
  struct two_d_arr *c1 =
      two_d_arr_init(ARRAY_SIZE(c1i), ARRAY_SIZE(c1i[0]), c1i);
  struct two_d_arr *q1 =
      two_d_arr_init(ARRAY_SIZE(q1i), ARRAY_SIZE(q1i[0]), q1i);
  int rs1, *pq1 = processQueries(5, c1->arr, c1->row_size, c1->col_size,
                                 q1->arr, q1->row_size, q1->col_size, &rs1);
  for (int i = 0; i < rs1; i++)
    printf("%d ", pq1[i]); // expect: 3 2 3
  printf("\n");
  free(pq1);
  two_d_arr_free(c1);
  two_d_arr_free(q1);
}