[AtCoder] ABC 138 D – Ki
問題
方針
幅優先探索
頂点 \( 1 \) から幅優先探索を行って全ての頂点のカウンターの値を計算します。そのために、頂点 \( i \) が最初のカウンターの値をあらかじめ計算します。最初のカウンターの値とは、ある頂点 \( u \) が \( u = p_i \ (1 \leq i \leq N)\) を満たすような頂点 \( u \) に \( x_i \) を加算した値です。ここで、頂点 \( i \) のカウンターの値を \( c_i \) とします。
頂点 \( 1 \) を親として、子のカウンターの値に \( c_1 \) を加算するというように、親から子に向かってカウンターの値を加算していきます。この探索では、隣接リストとキューを用いて幅優先探索を行うことができます。
コード
#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { int N, Q; cin >> N >> Q; int a[N - 1], b[N - 1]; // 隣接リスト vector<int> adj[N]; for (int i = 0; i < N - 1; i++) { cin >> a[i] >> b[i]; a[i]--; b[i]--; adj[a[i]].push_back(b[i]); adj[b[i]].push_back(a[i]); } int p[Q]; ll x[Q]; ll c[N]{}; for (int i = 0; i < Q; i++) { cin >> p[i] >> x[i]; p[i]--; c[p[i]] += x[i]; } ll t = 0; deque<int> q; q.push_back(0); int vis[N]{}; vis[0] = 1; while(!q.empty()) { int u = q.front(); q.pop_front(); for (int i : adj[u]) { if (vis[i] == 1) continue; vis[i] = 1; c[i] += c[u]; q.push_back(i); } } for (int i = 0; i < N; i++) { if (i == N - 1) { cout << c[i] << "\n"; } else { cout << c[i] << " "; } } return 0; }
ディスカッション
コメント一覧
まだ、コメントがありません