Problem p03600 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, int> P;
typedef pair<ll, pair<int, int>> P3;

const ll MOD = ll(1e9 + 7);
const ll LLINF = LLONG_MAX;
const int IINF = INT32_MAX;
const int MAX_N = int(1e5) + 5;
const int MAX_V = 305;
const double EPS = 1e-8;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)

ll n, d[305][305];

bool wf() {
  REP(k, n) {
    REP(i, n) {
      REP(j, n) {
        if (d[i][j] > d[i][k] + d[k][j]) {
          return false;
        }
      }
    }
  }
  return true;
}

struct UF {
  int p[305], r[305];

  void init(int _n) {
    REP(i, _n) {
      p[i] = i;
      r[i] = 1;
    }
  }
  int find(int x) {
    if (p[x] == x)
      return x;
    else
      return p[x] = find(p[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    if (r[x] == r[y])
      r[x]++;
    p[y] = x;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

struct edge {
  ll to, cost;
};

int V;
vector<edge> G[MAX_V];
ll dmin[MAX_V];

void dijkstra(int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(dmin, dmin + V, LLINF);
  dmin[s] = 0;
  que.push(P(0, s));

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (dmin[v] < p.first)
      continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (dmin[e.to] > dmin[v] + e.cost) {
        dmin[e.to] = dmin[v] + e.cost;
        que.push(P(dmin[e.to], e.to));
      }
    }
  }
}

ll solve() {
  vector<P3> es;
  REP(i, n) {
    REP(j, n) {
      if (i == j)
        continue;
      es.push_back(P3(d[i][j], {i, j}));
    }
  }
  sort(es.begin(), es.end());
  UF g;
  g.init(n);
  ll sum = 0;
  REP(i, es.size()) {
    int u = es[i].second.first, v = es[i].second.second;
    if (!g.same(u, v)) {
      sum += es[i].first;
      g.unite(u, v);
      G[u].push_back({v, es[i].first});
      G[v].push_back({u, es[i].first});
    } else {
      dijkstra(u);
      if (dmin[v] > d[u][v]) {
        sum += es[i].first;
        G[u].push_back({v, es[i].first});
        G[v].push_back({u, es[i].first});
      }
    }
  }
  return sum;
}

int main() {
  cin >> n;
  REP(i, n) {
    REP(j, n) { cin >> d[i][j]; }
  }
  if (!wf())
    cout << -1 << endl;
  else {
    V = n;
    cout << solve() << endl;
  }
  return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, int> P;
typedef pair<ll, pair<int, int>> P3;

const ll MOD = ll(1e9 + 7);
const ll LLINF = LLONG_MAX;
const int IINF = INT32_MAX;
const int MAX_N = int(1e5) + 5;
const int MAX_V = 305;
const double EPS = 1e-8;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)

ll n, d[305][305];

bool wf() {
  REP(k, n) {
    REP(i, n) {
      REP(j, n) {
        if (d[i][j] > d[i][k] + d[k][j]) {
          return false;
        }
      }
    }
  }
  return true;
}

struct UF {
  int p[305], r[305];

  void init(int _n) {
    REP(i, _n) {
      p[i] = i;
      r[i] = 1;
    }
  }
  int find(int x) {
    if (p[x] == x)
      return x;
    else
      return p[x] = find(p[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    if (r[x] == r[y])
      r[x]++;
    p[y] = x;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

struct edge {
  ll to, cost;
};

int V;
vector<edge> G[MAX_V];
ll dmin[MAX_V];

void dijkstra(int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(dmin, dmin + V, LLINF);
  dmin[s] = 0;
  que.push(P(0, s));

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (dmin[v] < p.first)
      continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (dmin[e.to] > dmin[v] + e.cost) {
        dmin[e.to] = dmin[v] + e.cost;
        que.push(P(dmin[e.to], e.to));
      }
    }
  }
}

ll solve() {
  vector<P3> es;
  REP(i, n) {
    FOR(j, i + 1, n) {
      if (i == j)
        continue;
      es.push_back(P3(d[i][j], {i, j}));
    }
  }
  sort(es.begin(), es.end());
  UF g;
  g.init(n);
  ll sum = 0;
  REP(i, es.size()) {
    int u = es[i].second.first, v = es[i].second.second;
    if (!g.same(u, v)) {
      sum += es[i].first;
      g.unite(u, v);
      G[u].push_back({v, es[i].first});
      G[v].push_back({u, es[i].first});
    } else {
      dijkstra(u);
      if (dmin[v] > d[u][v]) {
        sum += es[i].first;
        G[u].push_back({v, es[i].first});
        G[v].push_back({u, es[i].first});
      }
    }
  }
  return sum;
}

int main() {
  cin >> n;
  REP(i, n) {
    REP(j, n) { cin >> d[i][j]; }
  }
  if (!wf())
    cout << -1 << endl;
  else {
    V = n;
    cout << solve() << endl;
  }
  return 0;
}