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

#include <bits/stdc++.h>
#define MAX_N 100011
#define N MAX_N
#define rank dfasfds
using namespace std;
typedef long long ll;
typedef vector<int> S;
int par[MAX_N], rank[MAX_N];
ll val[MAX_N];
S G[N];

void init(int n) {
  for (int i = 0; i < N; i++)
    par[i] = i, rank[i] = 0;
}

int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}

bool same(int x, int y) { return find(x) == find(y); }

void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y)
    return;
  if (rank[x] < rank[y])
    par[x] = y, val[y] += val[x];
  else {
    par[y] = x;
    val[x] += val[y];
    if (rank[x] == rank[y])
      rank[x]++;
  }
}

int used[N];
vector<int> path;
void dfs(int pos, int pre) {
  if (used[pos] || pos != find(pos)) {
    while (path.size())
      unite(0, path.back()), path.pop_back();
    return;
  }
  used[pos] = 1;
  path.push_back(pos);

  for (S::iterator it = G[pos].begin(); it != G[pos].end(); it++)
    if (*it != pre)
      dfs(*it, pos);
  used[pos] = 0;
  if (path.size() && path.back() == pos)
    path.pop_back();
}

vector<int> col[N];
ll get_mx(int pos) {
  pos = find(pos);
  used[pos] = 1;
  ll res = 0;

  for (int i = 0; i < col[pos].size(); i++)
    for (S::iterator it = G[col[pos][i]].begin(); it != G[col[pos][i]].end();
         it++)
      if (!used[find(*it)])
        res = max(res, get_mx(find(*it)));
  return res + val[find(pos)];
}

int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> val[i];
  for (int i = 0, a, b; i < m; i++) {
    cin >> a >> b;
    a--, b--;
    G[a].push_back(b);
    G[b].push_back(a);

    //    G[a].insert(b);
    //  G[b].insert(a);
  }
  init(n);
  dfs(0, -1);
  for (int i = 0; i < n; i++)
    col[find(i)].push_back(i);
  cout << get_mx(find(0)) << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define MAX_N 100011
#define N MAX_N
#define rank dfasfds
using namespace std;
typedef long long ll;
typedef unordered_set<int> S;
int par[MAX_N], rank[MAX_N];
ll val[MAX_N];
S G[N];

void init(int n) {
  for (int i = 0; i < N; i++)
    par[i] = i, rank[i] = 0;
}

int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}

bool same(int x, int y) { return find(x) == find(y); }

void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y)
    return;
  if (rank[x] < rank[y])
    par[x] = y, val[y] += val[x];
  else {
    par[y] = x;
    val[x] += val[y];
    if (rank[x] == rank[y])
      rank[x]++;
  }
}

int used[N];
vector<int> path;
void dfs(int pos, int pre) {
  if (used[pos] || pos != find(pos)) {
    for (int i = 0; i < path.size(); i++)
      unite(pos, path[i]);
    return;
  }
  used[pos] = 1;
  path.push_back(pos);
  for (S::iterator it = G[pos].begin(); it != G[pos].end(); it++)
    if (*it != pre)
      dfs(*it, pos);
  used[pos] = 0;
  path.pop_back();
}

vector<int> col[N];
ll get_mx(int pos) {
  pos = find(pos);
  used[pos] = 1;
  ll res = 0;

  for (int i = 0; i < col[pos].size(); i++)
    for (S::iterator it = G[col[pos][i]].begin(); it != G[col[pos][i]].end();
         it++)
      if (!used[find(*it)])
        res = max(res, get_mx(find(*it)));
  return res + val[find(pos)];
}

int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> val[i];
  for (int i = 0, a, b; i < m; i++) {
    cin >> a >> b;
    a--, b--;
    G[a].insert(b);
    G[b].insert(a);
  }
  init(n);
  dfs(0, -1);
  for (int i = 0; i < n; i++)
    col[find(i)].push_back(i);
  cout << get_mx(find(0)) << endl;

  return 0;
}