https://beta.atcoder.jp/contests/arc083/tasks/arc083_b
解説
https://beta.atcoder.jp/contests/arc083/submissions/1604142
全ての辺を張っておき、いらない辺を削除していくことで最適な答えを得る。
削除する辺はコストが大きいものから順に選んだが、小さい順でも行けるかも(よく分かってない)。
どこでもいいのである1頂点を経由して、
- A[a][i] + A[i][b]==A[a][b]であれば、A[a][b]の辺は消せる
- A[a][i] + A[i][b]
- A[a][i] + A[i][b]>A[a][b]であれば、A[a][b]は必要なので何もしない(残す)
これを順にやって答え
typedef long long ll; int N, A[303][303]; ll d[303][303]; #define INF INT_MAX/2 //--------------------------------------------------------------------------------------------------- void _main() { cin >> N; rep(i, 0, N) rep(j, 0, N) cin >> A[i][j]; vector<pair<ll, pair<int, int>>> v; rep(i, 0, N) rep(j, i + 1, N) v.push_back({ -A[i][j],{ i,j } }); sort(v.begin(), v.end()); ll ans = 0; rep(i, 0, N) rep(j, i + 1, N) ans += A[i][j]; fore(p, v) { ll c = -p.first; int a = p.second.first; int b = p.second.second; if (A[a][b] == INF) continue; rep(i, 0, N) if (i != a && i != b && A[a][i] != INF && A[i][b] != INF) { if (A[a][i] + A[i][b] == c) { ans -= c; A[a][b] = A[b][a] = INF; break; } else if (A[a][i] + A[i][b] < c) { printf("-1\n"); return; } } } cout << ans << endl; }