#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M, Q;
if (!(cin >> N >> M >> Q)) return 0;
vector<vector<int>> g(N), gr(N);
for (int i = 0; i < M; ++i) {
int a, b; cin >> a >> b;
--a; --b; // convert to 0-based
g[a].push_back(b); // edge a -> b (from higher to lower town index)
gr[b].push_back(a); // reverse edge b <- a
}
// We'll use timestamp technique for per-query marking to avoid clearing large arrays.
vector<int> mark_reach(N, 0);
vector<int> mark_block(N, 0);
int cur_mark = 1;
vector<int> qqueue;
vector<int> nodes_in_R; nodes_in_R.reserve(N);
vector<int> dp(N, INT_MIN);
for (int qi = 0; qi < Q; ++qi, ++cur_mark) {
int T, Y;
cin >> T >> Y;
--T;
// read blocked list, mark them (timestamped)
for (int i = 0; i < Y; ++i) {
int x; cin >> x; --x;
mark_block[x] = cur_mark;
}
// 1) reverse BFS/DFS from T to find all nodes that can reach T
qqueue.clear();
nodes_in_R.clear();
// BFS using vector as queue
int head = 0;
qqueue.push_back(T);
mark_reach[T] = cur_mark;
while (head < (int)qqueue.size()) {
int u = qqueue[head++];
nodes_in_R.push_back(u);
for (int p : gr[u]) {
if (mark_reach[p] != cur_mark) {
mark_reach[p] = cur_mark;
qqueue.push_back(p);
}
}
}
if (nodes_in_R.empty()) {
// only possible if graph empty and T isolated; but nodes_in_R contains T always
cout << -1 << '\n';
continue;
}
// 2) Process nodes in decreasing index order (valid topological order because edges go from smaller->larger index)
// but we should process nodes_in_R sorted descending to be safe.
sort(nodes_in_R.begin(), nodes_in_R.end(), greater<int>());
// initialize dp for nodes in R
for (int u : nodes_in_R) dp[u] = INT_MIN;
dp[T] = 0;
for (int u : nodes_in_R) {
if (u == T) continue;
int best = INT_MIN;
// u -> v; we only consider v that are in R (mark_reach == cur_mark)
for (int v : g[u]) {
if (mark_reach[v] == cur_mark && dp[v] != INT_MIN) {
best = max(best, dp[v] + 1);
}
}
dp[u] = best;
}
// 3) find maximum among unblocked nodes in R that can reach T (dp[u] != INT_MIN)
int ans = INT_MIN;
for (int u : nodes_in_R) {
if (dp[u] == INT_MIN) continue; // cannot reach T
if (mark_block[u] == cur_mark) continue; // busy friend, skip as a source
ans = max(ans, dp[u]);
}
if (ans == INT_MIN) cout << -1 << '\n';
else cout << ans << '\n';
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |