Problem p03602 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;

struct UnionFind {
  vector<int> parent;

  UnionFind() {}

  UnionFind(int nmemb) { init(nmemb); }

  void init(int nmemb) {
    parent.clear();
    parent.assign(nmemb, -1);
  }

  int root(int x) {
    if (parent[x] < 0) {
      return x;
    }
    return parent[x] = root(parent[x]);
  }

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

  void unite(int x, int y) {
    x = root(x);
    y = root(y);

    if (x == y)
      return;

    parent[x] += parent[y];
    parent[y] = x;

    return;
  }
};
//===

UnionFind uf(305);
struct Edge {
  ll len, to, from;
};
auto cmp = [](const Edge &x, const Edge &y) {
  if (x.len < y.len)
    return true;
  else
    return false;
};

ll n;
ll a[305][305];
ll tmp[305][305];
vector<Edge> e;
ll ans;

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (i == j)
        tmp[i][j] = 0;
      else
        tmp[i][j] = 1ll << 60ll;

      cin >> a[i][j];

      e.push_back((Edge){a[i][j], i, j});
    }
  }

  sort(e.begin(), e.end(), cmp);

  for (int i = 0; i < e.size(); i++) {
    Edge s = e[i];

    if (tmp[s.to][s.from] != s.len) {
      tmp[s.to][s.from] = s.len;
      tmp[s.from][s.to] = s.len;
      ans += s.len;

      int k = s.from;
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          tmp[i][j] = min(tmp[i][j], tmp[i][k] + tmp[k][j]);
        }
      }

      k = s.to;
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          tmp[i][j] = min(tmp[i][j], tmp[i][k] + tmp[k][j]);
        }
      }
    }
  }

  for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        tmp[i][j] = min(tmp[i][j], tmp[i][k] + tmp[k][j]);
      }
    }
  }

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (tmp[i][j] != a[i][j]) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;

struct UnionFind {
  vector<int> parent;

  UnionFind() {}

  UnionFind(int nmemb) { init(nmemb); }

  void init(int nmemb) {
    parent.clear();
    parent.assign(nmemb, -1);
  }

  int root(int x) {
    if (parent[x] < 0) {
      return x;
    }
    return parent[x] = root(parent[x]);
  }

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

  void unite(int x, int y) {
    x = root(x);
    y = root(y);

    if (x == y)
      return;

    parent[x] += parent[y];
    parent[y] = x;

    return;
  }
};
//===

UnionFind uf(305);
struct Edge {
  ll len, to, from;
};
auto cmp = [](const Edge &x, const Edge &y) {
  if (x.len < y.len)
    return true;
  else
    return false;
};

ll n;
ll a[305][305];
ll tmp[305][305];
vector<Edge> e;
ll ans;

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (i == j)
        tmp[i][j] = 0;
      else
        tmp[i][j] = 1ll << 60ll;

      cin >> a[i][j];

      e.push_back((Edge){a[i][j], i, j});
    }
  }

  sort(e.begin(), e.end(), cmp);

  for (int i = 0; i < e.size(); i++) {
    Edge s = e[i];

    if (tmp[s.to][s.from] > s.len) {
      tmp[s.to][s.from] = s.len;
      tmp[s.from][s.to] = s.len;
      ans += s.len;

      int k = s.from;
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          tmp[i][j] = min(tmp[i][j], tmp[i][k] + tmp[k][j]);
        }
      }

      k = s.to;
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          tmp[i][j] = min(tmp[i][j], tmp[i][k] + tmp[k][j]);
        }
      }
    }
  }

  for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        tmp[i][j] = min(tmp[i][j], tmp[i][k] + tmp[k][j]);
      }
    }
  }

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (tmp[i][j] != a[i][j]) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  cout << ans << endl;

  return 0;
}