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

#include <algorithm>
#include <climits>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

struct Tag {
  int a, b;
  int w;

  bool operator<(const Tag &other) const { return w < other.w; }
};

// Verified PKU 2524
int getroot(int i, vector<int> &roots) {
  if (roots[i] == i)
    return i;
  else
    return (roots[i] = getroot(roots[i], roots));
}

// Verified PKU 2524
bool unite(int i, int j, vector<int> &roots, vector<int> &levels) {
  i = getroot(i, roots);
  j = getroot(j, roots);
  if (i == j)
    return false;

  if (levels[i] < levels[j]) {
    roots[i] = j;
  } else {
    roots[j] = i;
    if (levels[i] == levels[j])
      ++levels[i];
  }
  return true;
}

int main() {
  while (true) {
    int N, M;
    cin >> N >> M;
    if (!N && !M)
      break;

    vector<Tag> v;

    for (int i = 0; i < M; ++i) {
      Tag t;
      cin >> t.a >> t.b >> t.w;
      v.push_back(t);
    }

    sort(v.begin(), v.end());

    int ans = INT_MAX;
    if (v.size() < N - 1) {
      ans = -1;
      goto next;
    }

    for (int start = 0; start < v.size(); ++start) {
      int left = start - 1, right = start + 1;
      int cnt = 1;
      int mincost = v[start].w, maxcost = v[start].w;

      vector<int> roots(N + 1), levels(N + 1, 0);
      for (int i = 0; i < roots.size(); ++i)
        roots[i] = i;
      unite(v[start].a, v[start].b, roots, levels);

      /*
      for(cnt = 2; cnt <= N-1; ++cnt) {
          while(left >= 0 && getroot(v[left].a, roots) == getroot(v[left].b,
      roots)) --left; while(right < v.size() && getroot(v[right].a, roots) ==
      getroot(v[right].b, roots)) ++right;

          int dl = INT_MAX, dr = INT_MAX;
          if(left >= 0) {
              dl = maxcost - v[left].w;
          }
          if(right < v.size()) {
              dr = v[right].w - mincost;
          }

          if(dl < dr) {
              mincost = v[left].w;
              unite(v[left].a, v[left].b, roots, levels);
          }
          else if(dr != INT_MAX) {
              maxcost = v[right].w;
              unite(v[right].a, v[right].b, roots, levels);
          }
          else {
              ans = -1;
              goto next;
          }
      }
      */
      cnt = 1;
      for (int i = start + 1; i < v.size(); ++i) {
        if (getroot(v[i].a, roots) == getroot(v[i].b, roots))
          continue;
        // cout << "Connect " << v[i].a << ' ' << v[i].b << endl;
        unite(v[i].a, v[i].b, roots, levels);
        mincost = min(mincost, v[i].w);
        maxcost = max(maxcost, v[i].w);
        ++cnt;
      }
      if (cnt == N - 1) {
        // cout << "Cost: " << maxcost-mincost << endl << endl;
        ans = min(ans, maxcost - mincost);
      } else {
        // cout << "Not spanning" << endl << endl;
      }
    }
  next:
    if (ans == INT_MAX)
      ans = -1;
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <climits>
#include <deque>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

int main() {
  while (true) {
    int N, M;
    cin >> N >> M;
    if (!N && !M)
      break;

    vector<vector<int>> v(N, vector<int>(N, -1));

    vector<bool> connected(N, false);
    int connectcnt = 0;
    for (int i = 0; i < M; ++i) {
      int a, b, w;
      cin >> a >> b >> w;
      --a;
      --b;
      v[a][b] = v[b][a] = w;

      if (!connected[a])
        ++connectcnt;
      if (!connected[b])
        ++connectcnt;

      connected[a] = connected[b] = true;
    }

    if (connectcnt != N) {
      cout << -1 << endl;
      continue;
    }

    int ans = INT_MAX;
    vector<vector<bool>> checked(N, vector<bool>(N, false));
    for (int sa = 0; sa < N; ++sa) {
      for (int sb = sa + 1; sb < N; ++sb) {
        if (v[sa][sb] == -1)
          continue;
        vector<bool> used(N, false);
        deque<int> unused_node;
        deque<int> used_node;

        for (int i = 0; i < N; ++i)
          if (i != sa && i != sb)
            unused_node.push_back(i);

        used_node.push_back(sa);
        used_node.push_back(sb);

        int mincost = v[sa][sb];
        int maxcost = v[sa][sb];
        used[sa] = used[sb] = true;
        for (int i = 2; i < N; ++i) {
          int bestj, bestk;
          int bestdiff = INT_MAX;
          for (int j = 0; j < used_node.size(); ++j) {
            for (int k = 0; k < unused_node.size(); ++k) {
              int a = used_node[j];
              int b = unused_node[k];
              if (mincost <= v[a][b] && v[a][b] <= maxcost) {
                bestj = j;
                bestk = k;
                bestdiff = 0;
                goto endjk;
              } else if (v[a][b] < mincost) {
                if (maxcost - v[a][b] < bestdiff) {
                  bestj = j;
                  bestk = k;
                  bestdiff = maxcost - v[a][b];
                }
              } else if (maxcost < v[a][b]) {
                if (v[a][b] - mincost < bestdiff) {
                  bestj = j;
                  bestk = k;
                  bestdiff = v[a][b] - mincost;
                }
              }
            }
          }
        endjk:
          int a = used_node[bestj], b = unused_node[bestk];
          used[b] = true;
          if (bestdiff > 0) {
            if (v[a][b] < mincost) {
              mincost = v[a][b];
            } else {
              maxcost = v[a][b];
            }
          }

          if (maxcost - mincost >= ans)
            break;
          used_node.push_back(b);
          unused_node.erase(unused_node.begin() + bestk);
          checked[a][b] = checked[b][a] = true;
        }
        ans = min(ans, maxcost - mincost);
      }
    }

    cout << ans << endl;
  }

  return 0;
}