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

#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
vector<int> g[3100];
vector<int> ng[3100];
int deg[3100];
int use[3100];
pair<int, int> edge[31000];
int M;
int N;
int dfs(int a, int b) {
  for (int i = a; i < M; i++) {
    int L = edge[i].first;
    int R = edge[i].second;
    if (use[L] != 1 && use[R] != 1) {
      if (b == 0)
        return -1;
      if (deg[L] < deg[R])
        swap(L, R);
      int best = -1;
      // use L
      use[L] = 1;
      int nb = b - 1;
      vector<int> rev;
      for (int j = 0; j < g[L].size(); j++) {
        if (use[g[L][j]] != 1) {
          rev.push_back(g[L][j]);
          deg[g[L][j]]--;
        }
      }
      if (!(deg[L] <= 1 && deg[R] > 1))
        best = max(best, dfs(i + 1, nb));
      for (int j = 0; j < rev.size(); j++)
        deg[rev[j]]++;
      // not use L
      use[L] = 0;
      rev.clear();
      nb = b;
      for (int j = 0; j < g[L].size(); j++) {
        if (use[g[L][j]] != 1) {
          use[g[L][j]] = 1;
          nb--;
          rev.push_back(g[L][j]);
        }
      }
      for (int j = 0; j < rev.size(); j++) {
        for (int k = 0; k < g[rev[j]].size(); k++) {
          deg[g[rev[j]][k]]--;
        }
      }
      if (nb >= 0 && !(deg[L] > 1 && deg[R] <= 1))
        best = max(best, dfs(i + 1, nb));
      for (int j = 0; j < rev.size(); j++) {
        for (int k = 0; k < g[rev[j]].size(); k++) {
          deg[g[rev[j]][k]]++;
        }
      }
      use[L] = -1;
      for (int j = 0; j < rev.size(); j++)
        use[rev[j]] = -1;
      return best;
    }
  }
  return b;
}
int main() {
  int a, b, c;
  scanf("%d%d%d", &a, &b, &c);
  N = a;
  // M=b;
  for (int i = 0; i < b; i++) {
    int p, q;
    scanf("%d%d", &p, &q);
    p--;
    q--;
    g[p].push_back(q);
    g[q].push_back(p);
    deg[p]++;
    deg[q]++;
    edge[i] = make_pair(p, q);
  }
  for (int i = 0; i < a; i++)
    use[i] = -1;
  for (int i = 0; i < a; i++)
    if (deg[i] < 1)
      use[i] = 0;
  int rem = c;
  while (1) {
    int at = -1;
    for (int i = 0; i < a; i++) {
      if (deg[i] > c) {
        at = i;
        break;
      }
    }
    if (~at) {
      use[at] = 1;
      rem--;
      for (int i = 0; i < g[at].size(); i++) {
        deg[g[at][i]]--;
      }
      deg[at] = 0;
    } else
      break;
  }
  if (rem < 0) {
    printf("Impossible\\n");
    return 0;
  }
  for (int i = 0; i < b; i++) {
    if (use[edge[i].first] != 1 && use[edge[i].second] != 1) {
      edge[M++] = edge[i];
    }
  }
  if (M > c * c) {
    printf("Impossible\\n");
    return 0;
  }
  for (int i = 0; i < a; i++)
    for (int j = 0; j < g[i].size(); j++) {
      if (use[i] != 1 && use[g[i][j]] != 1)
        ng[i].push_back(g[i][j]);
    }
  for (int i = 0; i < a; i++)
    g[i] = ng[i];
  for (int i = 0; i < a; i++)
    deg[i] = g[i].size();
  int res = dfs(0, rem);
  if (res == -1)
    printf("Impossible\\n");
  else
    printf("%d\\n", c - res);
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
vector<int> g[3100];
int deg[3100];
int use[3100];
pair<int, int> edge[31000];
int M;
int N;
int dfs(int a, int b) {
  for (int i = a; i < M; i++) {
    int L = edge[i].first;
    int R = edge[i].second;
    if (use[L] != 1 && use[R] != 1) {
      if (b == 0)
        return -1;
      int best = -1;
      // use L
      use[L] = 1;
      int nb = b - 1;
      best = max(best, dfs(i + 1, nb));
      // not use L
      use[L] = 0;
      vector<int> rev;
      nb = b;
      for (int j = 0; j < g[L].size(); j++) {
        if (use[g[L][j]] != 1) {
          use[g[L][j]] = 1;
          nb--;
          rev.push_back(g[L][j]);
        }
      }
      if (nb >= 0)
        best = max(best, dfs(i + 1, nb));
      use[L] = -1;
      for (int j = 0; j < rev.size(); j++)
        use[rev[j]] = -1;
      return best;
    }
  }
  return b;
}
int main() {
  int a, b, c;
  scanf("%d%d%d", &a, &b, &c);
  N = a;
  // M=b;
  for (int i = 0; i < b; i++) {
    int p, q;
    scanf("%d%d", &p, &q);
    p--;
    q--;
    g[p].push_back(q);
    g[q].push_back(p);
    deg[p]++;
    deg[q]++;
    edge[i] = make_pair(p, q);
  }
  for (int i = 0; i < a; i++)
    use[i] = -1;
  for (int i = 0; i < a; i++)
    if (deg[i] < 1)
      use[i] = 0;
  int rem = c;
  while (1) {
    int at = -1;
    for (int i = 0; i < a; i++) {
      if (deg[i] > c) {
        at = i;
        break;
      }
    }
    if (~at) {
      use[at] = 1;
      rem--;
      for (int i = 0; i < g[at].size(); i++) {
        deg[g[at][i]]--;
      }
      deg[at] = 0;
    } else
      break;
  }
  if (rem < 0) {
    printf("Impossible\\n");
    return 0;
  }
  for (int i = 0; i < b; i++) {
    if (use[edge[i].first] != 1 && use[edge[i].second] != 1) {
      edge[M++] = edge[i];
    }
  }
  if (M > c * c) {
    printf("Impossible\\n");
    return 0;
  }
  int res = dfs(0, rem);
  if (res == -1)
    printf("Impossible\\n");
  else
    printf("%d\\n", c - res);
}