Problem p00815 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define int long long
#define N 110
using namespace std;
const int INF = 1LL << 55;
int Max(int &a, int b) { return a = max(a, b); }
int Min(int &a, int b) { return a = min(a, b); }
struct dat {
  int cnt, num_door, dis;
};
int n;
vector<int> G[N];
vector<int> rec;
vector<dat> A;

bool can_add_edge(int a, int b, int r) {
  return A[a].cnt && A[b].cnt && A[a].dis - A[b].dis == r;
}

void add_edge(int a, int b) {
  assert(A[a].cnt-- && A[b].cnt--);
  //  cout<<"add_edge "<<a<<" "<<b<<endl;
  G[a].push_back(b);
  G[b].push_back(a);
  sort(G[a].begin(), G[a].end());
  sort(G[b].begin(), G[b].end());
}

void erase_edge(int a, int b) {
  A[a].cnt++, A[b].cnt++;
  for (auto it = G[a].begin(); it != G[a].end(); it++)
    if (*it == b) {
      G[a].erase(it);
      break;
    }
  for (auto it = G[b].begin(); it != G[b].end(); it++)
    if (*it == a) {
      G[b].erase(it);
      break;
    }
}

void dfs(int idx, int num) {
  if (idx >= (int)rec.size())
    return;
  int pos = num;
  // cout<<"idx="<<idx<<" pos="<<pos<<" num="<<num<<" dis="<<A[pos].dis<<endl;
  // for(dat a:A) cout<<"{"<<a.cnt<<","<<a.dis<<"}"<<" ";cout<<endl;

  while (idx < (int)rec.size() && rec[idx] < 0) {
    // cout<<rec[idx]<<endl;
    for (int i = 0; i < (int)A.size() - 1; i++) {
      if (!can_add_edge(i, pos, rec[idx]))
        continue;
      add_edge(i, pos);
      idx++;
      break;
    }
    while (pos && A[pos].cnt == 0)
      pos--;
  }
  if (idx >= (int)rec.size())
    return;

  while (A[pos].cnt == 0)
    pos--;
  A.push_back((dat){rec[idx], rec[idx], A[pos].dis + 1});
  add_edge(pos, num + 1);
  dfs(idx + 1, num + 1);
}

void solve() {
  n = 0;
  A.clear();
  A.push_back((dat){rec[0], rec[0], 0});
  dfs(1, 0);
}

signed main() {
  int q;
  cin >> q;
  while (q--) {
    for (int i = 0; i < N; i++)
      G[i].clear();
    rec.clear();
    for (int a; cin >> a, a;)
      rec.push_back(a);

    solve();

    for (int i = 0; i < (int)A.size(); i++) {
      cout << i + 1;
      for (int a : G[i])
        cout << " " << a + 1;
      cout << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
struct dat {
  int T, t, f, lap;
  dat() { T = t = f = lap = 0; }
  vector<dat> V;
  bool operator>(const dat &a) const { return T - t > a.T - a.t; }
};

bool onFront(const dat &a, const dat &b) {
  return a.f == b.f && 1.0 * a.t / a.T < 1.0 * b.t / b.T;
}
bool checkJam(const dat &a, const dat &b) {
  return onFront(a, b) && a.T - a.t < b.T - b.t;
}

int merge(vector<dat> &A, int idx) {
  dat &a = A[idx];
  for (int i = 0; i < (int)A.size(); i++) {
    dat &b = A[i];
    if (!checkJam(a, b))
      continue;
    a.t = 0, a.lap -= a.f, a.f = !a.f;
    b.V.push_back(a);
    A.erase(A.begin() + idx);
    return 1e9;
  }
  return a.T - a.t;
}

void Push(vector<dat> &A, dat &a) {
  for (int i = 0; i < (int)a.V.size(); i++)
    Push(A, a.V[i]);
  a.V.clear();
  if (a.lap)
    A.push_back(a);
}

int sim(vector<dat> A) {
  int res = 0, idx = 0;
  vector<dat> tmp[2] = {A};
  while (1) {
    vector<dat> &A = tmp[idx];
    idx = !idx;
    if (A.empty())
      break;
    sort(A.begin(), A.end(), greater<dat>());
    int mn = 1e9;
    for (int i = A.size() - 1; i >= 0; i--)
      mn = min(mn, merge(A, i));

    vector<dat> &nA = tmp[idx];
    tmp[idx].clear();
    for (int i = 0; i < (int)A.size(); i++)
      if (A[i].t + mn < A[i].T)
        A[i].t += mn, nA.push_back(A[i]);
      else
        A[i].t = 0, A[i].lap -= A[i].f, A[i].f = !A[i].f, Push(nA, A[i]);
    res += mn;
  }
  return res;
}

int main() {
  int n;
  while (cin >> n, n) {
    vector<dat> A(n);
    for (int i = 0; i < n; i++)
      cin >> A[i].T >> A[i].lap;
    cout << sim(A) << endl;
  }
  return 0;
}