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

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

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

struct UnionFind {
  vi data;
  UnionFind(int n) : data(n, -1) {}
  int Find(int i) { return data[i] < 0 ? i : (data[i] = Find(data[i])); }
  bool Unite(int a, int b) {
    a = Find(a), b = Find(b);
    if (a == b)
      return false;
    if (-data[a] < -data[b])
      swap(a, b);
    data[a] += data[b];
    data[b] = a;
    return true;
  }
  int Size(int i) { return -data[Find(i)]; }
};

struct Edge {
  int src, dst, weight;
  Edge() {}
  Edge(int s, int d, int w) : src(s), dst(d), weight(w) {}
};
typedef vector<vector<Edge>> Graph;
bool operator<(const Edge &a, const Edge &b) { return a.weight < b.weight; }
bool operator>(const Edge &a, const Edge &b) { return a.weight > b.weight; }

void solve(int n, vector<Edge> edges) {
  int m = edges.size();

  int mst_weight = 0;
  vi used(m);
  { // Kruskal
    UnionFind uf(n);
    rep(i, edges.size()) {
      Edge e = edges[i];
      if (uf.Unite(e.src, e.dst)) {
        mst_weight += e.weight;
        used[i] = true;
      }
    }
  }

  int count = 0, bridge_sum = 0;
  rep(i, m) if (used[i]) {
    Edge candidate = edges[i];
    edges.erase(begin(edges) + i);

    UnionFind uf(n);
    int connected_component = n, weight = 0;
    for (Edge e : edges) {
      bool flg = uf.Unite(e.src, e.dst);
      if (flg)
        weight += e.weight;
      connected_component -= flg;
    }
    if (connected_component > 1 || weight > mst_weight) {
      count++;
      bridge_sum += candidate.weight;
    }

    edges.insert(begin(edges) + i, candidate);
  }

  cout << count << ' ' << bridge_sum << endl;
}

int main() {
  for (int n, m; cin >> n >> m && n | m;) {
    vector<Edge> edges;
    rep(i, m) {
      int u, v, w;
      cin >> u >> v >> w;
      u--, v--;
      edges.emplace_back(u, v, w);
    }
    sort(all(edges));
    solve(n, edges);
  }
}

Error: TLE

Fixed submission:

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

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

struct UnionFind {
  vi data;
  UnionFind(int n) : data(n, -1) {}
  int Find(int i) { return data[i] < 0 ? i : (data[i] = Find(data[i])); }
  bool Unite(int a, int b) {
    a = Find(a), b = Find(b);
    if (a == b)
      return false;
    if (-data[a] < -data[b])
      swap(a, b);
    data[a] += data[b];
    data[b] = a;
    return true;
  }
  int Size(int i) { return -data[Find(i)]; }
};

struct Edge {
  int src, dst, weight;
  Edge() {}
  Edge(int s, int d, int w) : src(s), dst(d), weight(w) {}
};
typedef vector<vector<Edge>> Graph;
bool operator<(const Edge &a, const Edge &b) { return a.weight < b.weight; }
bool operator>(const Edge &a, const Edge &b) { return a.weight > b.weight; }

int Kruskal(int n, vector<Edge> es, vi &forest) {
  sort(all(es));
  UnionFind uf(n);
  int res = 0;
  rep(i, es.size()) {
    Edge e = es[i];
    if (uf.Unite(e.src, e.dst)) {
      res += e.weight;
      forest.push_back(i);
    }
  }
  return res;
}
int Kruskal(int n, vector<Edge> es) {
  vi forest;
  return Kruskal(n, es, forest);
}

int main() {
  for (int n, m; cin >> n >> m && n | m;) {
    vector<Edge> edges;
    rep(i, m) {
      int u, v, w;
      cin >> u >> v >> w;
      u--, v--;
      edges.emplace_back(u, v, w);
    }
    sort(all(edges));

    vi cands;
    int sum = Kruskal(n, edges, cands);
    cands.clear();
    rep(i, m) cands.push_back(i);

    int cnt = 0, bsum = 0;
    for (int ci : cands) {
      int weight = edges[ci].weight;
      edges[ci].weight = INF;
      if (Kruskal(n, edges) > sum) {
        cnt++;
        bsum += weight;
      }
      edges[ci].weight = weight;
    }
    cout << cnt << ' ' << bsum << endl;
  }
}