Problem p00550 (C++) — buggy submission, verdict: Memory Limit Exceeded


#include <bits/stdc++.h>
using namespace std;
#define REP(i, x) for (int i = 0; i < x; ++i)
#define FOR(i, x, y) for (int i = x; i < y; ++i)
#define ALL(a) a.begin(), a.end()
using ll = long long;

int n, m, q;

vector<int> graph[123456];
int dist[123456];
typedef pair<int, int> P;
void dijkstra() {
  REP(i, n) dist[i] = 123456789;
  dist[0] = 0;
  priority_queue<P, vector<P>, greater<P>> que;
  que.push({0, 0});
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int leng = p.first;
    int vect = p.second;
    if (leng > dist[vect])
      continue;
    for (int next : graph[vect]) {
      if (dist[next] > leng + 1) {
        dist[next] = leng + 1;
        que.push({dist[next], next});
      }
    }
  }
}
struct edge {
  int lf, rt;
  bool before;
};
vector<edge> input;
vector<int> tree[123456];
vector<int> query;
bool black[123456];
int blacknum = 1;
void color(int x) {
  if (black[x])
    return;
  black[x] = true;
  blacknum++;
  for (int ch : tree[x])
    color(ch);
}
void process(int ed) {
  int ldis = dist[input[ed].lf];
  int rdis = dist[input[ed].rt];
  if (ldis > rdis)
    swap(input[ed].lf, input[ed].rt);
  if (ldis == rdis)
    return;
  tree[input[ed].lf].push_back(input[ed].rt);
  if (black[input[ed].lf])
    color(input[ed].rt);
}

int main() {
  cin >> n >> m >> q;
  REP(i, m) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    input.push_back({u, v, true});
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  REP(i, q) {
    int r;
    cin >> r;
    --r;
    input[r].before = false;
    query.push_back(r);
  }
  black[0] = true;
  dijkstra();
  REP(i, m) {
    if (input[i].before) {
      process(i);
    }
  }
  stack<int> ans;
  for (auto que = query.rbegin(); que != query.rend(); ++que) {
    ans.push(n - blacknum);
    process(*que);
  }
  while (!ans.empty()) {
    cout << ans.top() << endl;
    ans.pop();
  }
  return 0;
}

Error: MLE

Fixed submission:


#include <cassert>
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;
using pii = pair<int, int>;

int n, m, q;
int u[234567], v[234567];
int r[234567];

vector<int> firstgr[123456];
int flag[123456];
struct node {
  int parnum;
  vector<int> child;
};
node web[123456];

bool isdead[123456];
vector<int> deadcell; //??????parent??????????????????????????????
void crawl(int v_) {
  if (web[v_].parnum == 0)
    return;
  --web[v_].parnum;
  if (web[v_].parnum == 0) {
    deadcell.push_back(v_);
    isdead[v_] = true;
  } else {
    return;
  }
  for (int ch : web[v_].child) {
    crawl(ch);
  }
}

int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d", u + i, v + i);
    --u[i];
    --v[i];
    firstgr[u[i]].push_back(v[i]);
    firstgr[v[i]].push_back(u[i]);
  }
  for (int j = 0; j < q; ++j) {
    scanf("%d", r + j);
    --r[j];
  }
  fill(flag, flag + 123456, -1);
  queue<pii> que; // first=???????????? second=????±?
  que.push({0, 0});
  while (!que.empty()) {
    pii qp = que.front();
    que.pop();
    if (flag[qp.first] != -1 && qp.second > flag[qp.first])
      continue;
    flag[qp.first] = qp.second;
    for (int nextv : firstgr[qp.first]) {
      if (flag[nextv] == -1) {
        que.push({nextv, qp.second + 1});
      }
    }
  }
  for (int i = 0; i < m; ++i) {
    int diff = flag[u[i]] - flag[v[i]];
    if (diff == 1) {
      web[v[i]].child.push_back(u[i]);
      ++web[u[i]].parnum;
    }
    if (diff == -1) {
      ++web[v[i]].parnum;
      web[u[i]].child.push_back(v[i]);
    }
  }
  fill(isdead, isdead + 123456, false);
  for (int j = 0; j < q; ++j) {
    int road = r[j];
    int diff = flag[u[road]] - flag[v[road]];
    if (diff == 1) {
      if (!isdead[u[road]])
        crawl(u[road]);
    }
    if (diff == -1) {
      if (!isdead[v[road]])
        crawl(v[road]);
    }
    printf("%d\\n", deadcell.size());
  }
  return 0;
}