Problem p01717 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

struct Edge {
  int v, w;
};
typedef vector<vector<Edge>> Graph;

const int INF = 1 << 28;
const int MAXN = 2020;

int N, M, K;
Graph G;
bool vis[MAXN];
int size;
int cost[MAXN];
int dp[MAXN][MAXN][2];
int C;
int Size[MAXN];
int V[MAXN][MAXN];
int dp2[MAXN][MAXN];

void dfs(int v, int src, int prev) {
  vis[v] = true;
  for (int i = 0; i < G[v].size(); ++i) {
    int nv = G[v][i].v;
    if (nv == prev)
      continue;
    cost[size++] = G[v][i].w;
    if (nv == src)
      continue;
    dfs(nv, src, v);
    break;
  }
}

void calc(int r, int v[]) {
  for (int s = 0; s < 2; ++s) {
    fill(dp[0][0], dp[MAXN][0], -INF);
    dp[1][s][s] = 0;
    for (int i = 1; i < size; ++i) {
      for (int j = 0; j < size; ++j) {
        for (int k = 0; k < 2; ++k) {
          if (dp[i][j][k] == -INF)
            continue;
          dp[i + 1][j][0] = max(dp[i + 1][j][0], dp[i][j][k]);
          int add = 0;
          if (k) {
            if (!cost[i - 1])
              continue;
            else
              add += cost[i - 1];
          }
          if (r && i + 1 == size && s) {
            if (!cost[i])
              continue;
            else
              add += cost[i];
          }
          dp[i + 1][j + 1][1] = max(dp[i + 1][j + 1][1], dp[i][j][k] + add);
        }
      }
    }
    for (int j = 0; j <= size; ++j) {
      v[j] = max(v[j], max(dp[size][j][0], dp[size][j][1]));
    }
  }
}

int main() {
  while (cin >> N >> M >> K) {
    G = Graph(N);
    for (int i = 0; i < M; ++i) {
      int a, b, c;
      cin >> a >> b >> c;
      --a;
      --b;
      G[a].push_back((Edge){b, c});
      G[b].push_back((Edge){a, c});
    }
    memset(vis, 0, sizeof(vis));
    fill(V[0], V[MAXN], -INF);
    C = 0;
    for (int r = 0; r < 2; ++r) {
      for (int i = 0; i < N; ++i) {
        if (vis[i])
          continue;
        if (!r && G[i].size() == 2)
          continue;
        size = 0;
        dfs(i, i, -1);
        size += !r;
        Size[C] = size;
        calc(r, V[C++]);
      }
    }
    fill(dp2[0], dp2[MAXN], -INF);
    dp2[0][0] = 0;
    for (int i = 0; i < C; ++i) {
      for (int j = 0; j <= K; ++j) {
        for (int k = 0; k <= Size[i] && j + k <= K; ++k) {
          if (dp2[i][j] == -INF)
            continue;
          dp2[i + 1][j + k] = max(dp2[i + 1][j + k], dp2[i][j] + V[i][k]);
        }
      }
    }
    if (dp2[C][K] == -INF)
      cout << "Impossible" << endl;
    else
      cout << dp2[C][K] << endl;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

struct Edge {
  int v, w;
};
typedef vector<vector<Edge>> Graph;

const int INF = 1 << 28;
const int MAXN = 2020;

int N, M, K;
Graph G;
bool vis[MAXN];
int size;
int cost[MAXN];
int dp[MAXN][MAXN][2];
int C;
int Size[MAXN];
int V[MAXN][MAXN];
int dp2[MAXN][MAXN];

void dfs(int v, int src, int prev) {
  vis[v] = true;
  for (int i = 0; i < G[v].size(); ++i) {
    int nv = G[v][i].v;
    if (nv == prev)
      continue;
    cost[size++] = G[v][i].w;
    if (nv == src)
      continue;
    dfs(nv, src, v);
    break;
  }
}

void calc(int r, int v[]) {
  for (int s = 0; s < 2; ++s) {
    fill(dp[0][0], dp[size + 1][0], -INF);
    dp[1][s][s] = 0;
    for (int i = 1; i < size; ++i) {
      for (int j = 0; j < size; ++j) {
        for (int k = 0; k < 2; ++k) {
          if (dp[i][j][k] == -INF)
            continue;
          dp[i + 1][j][0] = max(dp[i + 1][j][0], dp[i][j][k]);
          int add = 0;
          if (k) {
            if (!cost[i - 1])
              continue;
            else
              add += cost[i - 1];
          }
          if (r && i + 1 == size && s) {
            if (!cost[i])
              continue;
            else
              add += cost[i];
          }
          dp[i + 1][j + 1][1] = max(dp[i + 1][j + 1][1], dp[i][j][k] + add);
        }
      }
    }
    for (int j = 0; j <= size; ++j) {
      v[j] = max(v[j], max(dp[size][j][0], dp[size][j][1]));
    }
  }
}

int main() {
  while (cin >> N >> M >> K) {
    G = Graph(N);
    for (int i = 0; i < M; ++i) {
      int a, b, c;
      cin >> a >> b >> c;
      --a;
      --b;
      G[a].push_back((Edge){b, c});
      G[b].push_back((Edge){a, c});
    }
    memset(vis, 0, sizeof(vis));
    fill(V[0], V[MAXN], -INF);
    C = 0;
    for (int r = 0; r < 2; ++r) {
      for (int i = 0; i < N; ++i) {
        if (vis[i])
          continue;
        if (!r && G[i].size() == 2)
          continue;
        size = 0;
        dfs(i, i, -1);
        size += !r;
        Size[C] = size;
        calc(r, V[C++]);
      }
    }
    fill(dp2[0], dp2[MAXN], -INF);
    dp2[0][0] = 0;
    for (int i = 0; i < C; ++i) {
      for (int j = 0; j <= K; ++j) {
        for (int k = 0; k <= Size[i] && j + k <= K; ++k) {
          if (dp2[i][j] == -INF)
            continue;
          dp2[i + 1][j + k] = max(dp2[i + 1][j + k], dp2[i][j] + V[i][k]);
        }
      }
    }
    if (dp2[C][K] == -INF)
      cout << "Impossible" << endl;
    else
      cout << dp2[C][K] << endl;
  }
  return 0;
}