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

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

#define MAX 200000

int N;
vector<int> G[MAX];
bool visited[MAX];
int prenum[MAX], parent[MAX], lowest[MAX], timer;
vector<P> bridge;

void dfs(int v, int prev) {
  prenum[v] = lowest[v] = timer;
  timer++;
  visited[v] = true;

  int next;
  for (int i = 0; i < G[v].size(); i++) {
    next = G[v][i];
    if (!visited[next]) {
      parent[next] = v;
      dfs(next, v);
      lowest[v] = min(lowest[v], lowest[next]);
      if (prenum[v] < lowest[G[v][i]])
        bridge.push_back(P(min(v, G[v][i]), max(v, G[v][i])));
    } else if (next != prev) {
      lowest[v] = min(lowest[v], prenum[next]);
    }
  }
}

set<int> art_points() {
  for (int i = 0; i < N; i++) {
    visited[i] = false;
  }
  timer = 1;
  dfs(0, -1);

  set<int> ap;
  int np = 0;
  for (int i = 1; i < N; i++) {
    int p = parent[i];
    if (p == 0)
      np++;
    else if (prenum[p] < lowest[i])
      ap.insert(p);
  }
  if (np > 1)
    ap.insert(0);
  return ap;
}

int w[MAX];
vector<P> edge;
vector<P> n_bridge;
vector<int> ok_G[MAX];
int cnt;
bool used[100001];
int sum[100001];
int num[100001];
int siz[100001];
vector<int> graph[MAX];

void c_dfs(int v) {
  used[v] = true;
  num[v] = cnt;
  siz[cnt]++;
  sum[cnt] += w[v];
  for (int i = 0; i < ok_G[v].size(); i++) {
    if (num[ok_G[v][i]] == -1) {
      c_dfs(ok_G[v][i]);
    }
  }
}

int dp[100001];
int dp2[100001];

int solve2(int v, int p) {
  if (dp2[v] != -1)
    return dp2[v];
  int res = sum[v];
  int back = -1;
  for (int i = 0; i < graph[v].size(); i++) {
    if (p != graph[v][i]) {
      int va = solve2(graph[v][i], v);
      if (va != 0) {
        res += va;
        back = 0;
      }
    }
  }
  if (siz[v] >= 3)
    back = 0;
  dp2[v] = (back == 0) ? res : 0;
  return dp2[v];
}

int solve(int v, int p) {
  if (dp[v] != -1)
    return dp[v];
  int res = 0;
  for (int i = 0; i < graph[v].size(); i++) {
    if (p != graph[v][i]) {
      int va = solve2(graph[v][i], v);
      if (va != 0)
        res += va;
    }
  }
  int diff = 0;
  for (int i = 0; i < graph[v].size(); i++) {
    if (p != graph[v][i]) {
      int va = solve(graph[v][i], v);
      if (va - max(dp2[graph[v][i]], 0) > diff) {
        diff = va - max(0, dp2[graph[v][i]]);
      }
    }
  }
  res += diff;
  return (dp[v] = (res + sum[v]));
}

int main(void) {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d", &w[i]);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
    edge.push_back(P(a, b));
  }
  N = n;
  art_points();
  sort(bridge.begin(), bridge.end());
  for (int i = 0; i < m; i++) {
    int v = lower_bound(bridge.begin(), bridge.end(), edge[i]) - bridge.begin();
    if (!(v < bridge.size() && bridge[v] == edge[i])) {
      ok_G[edge[i].first].push_back(edge[i].second);
      ok_G[edge[i].second].push_back(edge[i].first);
    }
  }
  memset(num, -1, sizeof(num));
  for (int i = 0; i < n; i++) {
    if (num[i] == -1) {
      c_dfs(i);
      cnt++;
    }
  }
  for (int i = 0; i < bridge.size(); i++) {
    P p = bridge[i];
    graph[num[p.first]].push_back(num[p.second]);
    graph[num[p.second]].push_back(num[p.first]);
  }
  memset(dp, -1, sizeof(dp));
  memset(dp2, -1, sizeof(dp2));
  printf("%d\\n", solve(num[0], -1));
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

#define MAX 200000

int N;
vector<int> G[MAX];
bool visited[MAX];
int prenum[MAX], parent[MAX], lowest[MAX], timer;
vector<P> bridge;

void dfs(int v, int prev) {
  prenum[v] = lowest[v] = timer;
  timer++;
  visited[v] = true;

  int next;
  for (int i = 0; i < G[v].size(); i++) {
    next = G[v][i];
    if (!visited[next]) {
      parent[next] = v;
      dfs(next, v);
      lowest[v] = min(lowest[v], lowest[next]);
      if (prenum[v] < lowest[G[v][i]])
        bridge.push_back(P(min(v, G[v][i]), max(v, G[v][i])));
    } else if (next != prev) {
      lowest[v] = min(lowest[v], prenum[next]);
    }
  }
}

set<int> art_points() {
  for (int i = 0; i < N; i++) {
    visited[i] = false;
  }
  timer = 1;
  dfs(0, -1);

  set<int> ap;
  int np = 0;
  for (int i = 1; i < N; i++) {
    int p = parent[i];
    if (p == 0)
      np++;
    else if (prenum[p] < lowest[i])
      ap.insert(p);
  }
  if (np > 1)
    ap.insert(0);
  return ap;
}

int w[MAX];
vector<P> edge;
vector<P> n_bridge;
vector<int> ok_G[MAX];
int cnt;
bool used[100001];
int sum[100001];
int num[100001];
int siz[100001];
vector<int> graph[MAX];

void c_dfs(int v) {
  used[v] = true;
  num[v] = cnt;
  siz[cnt]++;
  sum[cnt] += w[v];
  for (int i = 0; i < ok_G[v].size(); i++) {
    if (num[ok_G[v][i]] == -1) {
      c_dfs(ok_G[v][i]);
    }
  }
}

int dp[100001];
int dp2[100001];

int solve2(int v, int p) {
  if (dp2[v] != -1)
    return dp2[v];
  int res = w[v];
  int back = -1;
  for (int i = 0; i < graph[v].size(); i++) {
    if (p != graph[v][i]) {
      int va = solve2(graph[v][i], v);
      if (va != -1) {
        res += va;
        back = 0;
      }
    }
  }
  if (siz[v] >= 3)
    back = 0;
  dp2[v] = (back == 0) ? res : -1;
  return dp2[v];
}

int solve(int v, int p) {
  if (dp[v] != -1)
    return dp[v];
  int res = 0;
  for (int i = 0; i < graph[v].size(); i++) {
    if (p != graph[v][i]) {
      int va = solve2(graph[v][i], v);
      if (va != -1)
        res += va;
    }
  }
  int diff = 0;
  for (int i = 0; i < graph[v].size(); i++) {
    if (p != graph[v][i]) {
      int va = solve(graph[v][i], v);
      if (va - max(dp2[v], 0) > diff) {
        diff = va - max(0, dp2[v]);
      }
    }
  }
  res += diff;
  return (dp[v] = (res + sum[v]));
}

int main(void) {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d", &w[i]);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
    edge.push_back(P(a, b));
  }
  N = n;
  art_points();
  sort(bridge.begin(), bridge.end());
  for (int i = 0; i < m; i++) {
    int v = lower_bound(bridge.begin(), bridge.end(), edge[i]) - bridge.begin();
    if (!(v < bridge.size() && bridge[v] == edge[i])) {
      ok_G[edge[i].first].push_back(edge[i].second);
      ok_G[edge[i].second].push_back(edge[i].first);
    }
  }
  memset(num, -1, sizeof(num));
  for (int i = 0; i < n; i++) {
    if (num[i] == -1) {
      c_dfs(i);
      cnt++;
    }
  }
  for (int i = 0; i < bridge.size(); i++) {
    P p = bridge[i];
    graph[num[p.first]].push_back(num[p.second]);
    graph[num[p.second]].push_back(num[p.first]);
  }
  memset(dp, -1, sizeof(dp));
  memset(dp2, -1, sizeof(dp2));
  printf("%d\\n", solve(num[0], -1));
  return 0;
}