問題
解法
以下の有向グラフを作り、DFSで頂点間の距離に矛盾が生じていないかを調べる。
- $ L_i $ から $ R_i $ まで距離 $ D_i $
- $ R_i $ から $ L_i $ まで距離 $ -D_i $
ただし、M個の入力から得られるグラフは連結していない場合があるため、その場合を考慮しなければならない。
n個全ての点について調べることで、連結していない場合もカバーできる。
#include <bits/stdc++.h> using namespace std; #define COUT(x) cout<<(x)<<"\n" #define REP(i, n) for(int i=0;i<n;i++) using P = pair<int,int>; using ll = long long; const int INF = 1e9; int n,m; vector<vector<P>> g(100010); void dfs() { queue<P> q; vector<int> dist(n, INF); // 全ての点について矛盾がないか調べる // グラフが連結していないケースがあるためnまでループして調べる REP(i,n) { if (dist[i] != INF) continue; // チェック済み // スタート地点は距離0とする q.push({ i, 0 }); dist[i] = 0; while(!q.empty()) { auto v = q.front(); q.pop(); int p = v.first; for(auto x: g[p]) { int np = x.first; int nd = dist[p] + x.second; if (dist[np] == INF) { dist[np] = nd; q.push(x); } else { // 距離に矛盾があるため終了 if (dist[np] != nd) { COUT("No"); return; } } } } } COUT("Yes"); } int main() { cin >> n >> m; // m == 0 の場合はそもそも矛盾しない if (m == 0) { COUT("Yes"); return 0; } vector<int> l(m),r(m),d(m); REP(i,m) { cin >> l[i] >> r[i] >> d[i]; l[i]--; r[i]--; // 0 index } REP(i,m) { g[l[i]].push_back({r[i], d[i]}); g[r[i]].push_back({l[i], -d[i]}); } dfs(); return 0; }