[AtCoder] ABC 087 D – People on a Line
問題
方針
座標間の距離が与えられるので、相対的な位置が分かります。したがって、ある座標の値を \( x_i = 0 \) として、\( M \) 個の情報に誤りがあるかどうかを調べます。
グラフ
各座標をグラフの頂点として、\( M \) 個の辺からなるグラフを考えます。\( M \) 個の情報から隣接リストを作成します。この隣接リストに座標間の距離の情報も追加しておきます。この座標間の距離は辺の重みではないことに注意します。例えば、\( (L_i, R_i, D_i) \) という情報から、頂点 \( L_i \) の隣接する頂点は \( R_i \) であり、距離は \( D_i \) であり、頂点 \( R_i \) の隣接する頂点は \( L_i \) であり、距離は \( -D_i \) であるという隣接リストが得られます。
幅優先探索
よくあるグラフの幅優先探索を行います。一度も訪れたことがない頂点 \( i \) の座標を \( x_i = 0 \) として、座標 \( i \) を含むグラフを走査します。このグラフを走査するなかで、座標の値を更新してき、誤りがあるかどうかを調べます。例えば、グラフ \( G \) の頂点が \( (1, 2, 3) \) であり、点 \( 1 \) に隣接する頂点が \( 2, 3)\) であり、頂点 \( 2 \) に隣接する頂点が \( 3 \) であるとします。ここで、 頂点 \( 1 \) から幅優先探索を行うと、\( x_2, x_3 \) の値が定まります。次に、頂点 \( 2 \) から頂点 \( 3 \) へ訪れたとき、\( x_3 \) の値が更新されるとき誤りがあることになります。
コード
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct Node { int id, cost; Node(int id, int cost) : id(id), cost(cost){} }; int main() { int N, M; cin >> N >> M; int L[M], R[M], D[M]; vector<Node> adj[N]; for (int i = 0; i < M; i++) { cin >> L[i] >> R[i] >> D[i]; L[i]--; R[i]--; adj[L[i]].push_back(Node(R[i], D[i])); adj[R[i]].push_back(Node(L[i], -D[i])); } int x[N]; int flag[N]{}; fill(x, x + N, INT32_MAX); for (int i = 0; i < N; i++) { if (flag[i] != 0) continue; x[i] = 0; deque<int> q; q.push_back(i); while (!q.empty()) { int v = q.front(); flag[v] = 1; q.pop_front(); for (int j = 0; j < adj[v].size(); j++) { int id = adj[v][j].id; int cost = adj[v][j].cost; if (x[id] == INT32_MAX) { x[id] = x[v] + cost; q.push_back(id); flag[id] = 1; } else { if (x[id] != x[v] + cost) { cout << "No\n"; return 0; } } } } } cout << "Yes\n"; return 0; }
ディスカッション
コメント一覧
まだ、コメントがありません