難易度評価

難易度を1〜10段階で評価できます。投票はあとから変更・取り消しできます。

難易度(投票) Lv.4.0 (1票)

投票の分布
  1. Lv.10票
  2. Lv.20票
  3. Lv.30票
  4. Lv.41票
  5. Lv.50票
  6. Lv.60票
  7. Lv.70票
  8. Lv.80票
  9. Lv.90票
  10. Lv.100票

難易度の目安を見る ↗

ログインして難易度を投票

外部サイトへ移動します

リンク先の URL を確認してから開いてください。

別タブで開く

Painting Graph

作成者 webp

難易度(作成者設定) Lv.3

難易度(投票) Lv.4.0 (1票)

解法のヒントになることがあります。
実行時間制限
2 秒
メモリ制限
512 MiB

解説

操作を逆順に行うと、以下のように処理できます。

  • i=Q,Q−1,…,1i = Q, Q-1,\ldots, 1 について以下を行う。
    • 頂点 XiX_i から辺を 00 本以上たどって到達可能な頂点のうち、まだ以前の操作によって色が塗られていない頂点を色 YiY_i で塗る。
  • 操作によって色が塗られなかった頂点を色 00 で塗る。

各操作で頂点 XiX_i から愚直にBFSやDFSを行って色を塗ると、計算量は O(Q(N+M))O(Q(N+M)) になります。

ここで、ある頂点が以前の操作によって色が塗られている場合、その頂点から辺を 00 本以上たどって到達可能なすべての頂点も必ず以前の操作によって色が塗られているため、その頂点から先を探索する必要はありません。

よって、BFSやDFSを行うとき、すでに色が塗られた頂点で探索を打ち切ることで、各頂点から伸びる辺を調べる回数が高々 11 回になります。したがって、全体で O(N+M+Q)O(N+M+Q) で処理できます。

再帰関数を用いてDFSを行うとスタックオーバーフローが発生する可能性がありますが、ジャッジでは AC を得られました。

解答例 (C++)
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<int>> to(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--; b--;
    to[a].push_back(b);
  }

  int q;
  cin >> q;
  vector<int> x(q), y(q);
  for (int i = 0; i < q; i++) {
    cin >> x[i] >> y[i];
    x[i]--;
  }

  vector<int> c(n);
  for (int i = q-1; i >= 0; i--) {
    if (c[x[i]] != 0) continue;
    c[x[i]] = y[i];
    queue<int> que;
    que.push(x[i]);
    while (que.size()) {
      int v = que.front(); que.pop();
      for (int u : to[v]) {
        if (c[u] != 0) continue;
        c[u] = y[i];
        que.push(u);
      }
    }
  }

  for (int i = 0; i < n; i++) {
    cout << c[i] << " \n"[i == n-1];
  }
  return 0;
}
解答例 (Python)
from collections import deque

n, m = map(int, input().split())
to = [[] for _ in range(n)]
for i in range(m):
  a, b = map(int, input().split())
  a, b = a-1, b-1
  to[a].append(b)

q = int(input())
x, y = [0] * q, [0] * q
for i in range(q):
  x[i], y[i] = map(int, input().split())
  x[i] -= 1

c = [0] * n
for i in reversed(range(q)):
  if c[x[i]] != 0: continue
  c[x[i]] = y[i]
  que = deque([x[i]])
  while len(que):
    v = que.popleft()
    for u in to[v]:
      if c[u] != 0: continue
      c[u] = y[i]
      que.append(u)

print(*c)

ユーザー解説

ユーザー解説を書く

ユーザー解説はまだありません。