#include <bits/stdc++.h>
#define hash _hash_
#define y1 _y1_
#define left _left_
#define right _right_
#define dec _dec_
using namespace std;
using ll = long long;
/*----------- I alone decide my fate! ------------*/
/* I just do what I gotta, in the heat of the summer... */
const int MAXN = 100000 + 5;
const int B = 316; // ≈ √(ΣY) với ΣY ≤100k → 316
int N, M, Q;
vector<int> adj[MAXN], radj[MAXN];
vector<pair<int,int>> best[MAXN]; // (len, start), giảm dần len
bool ban[MAXN]; // cờ đỉnh bận
// cho merge: đánh dấu nhanh các start đã thêm
int seen[MAXN], merge_timer = 0;
/// gộp src → dst, cộng len+1, giữ tối đa B, loại trùng start O(1)
void merge_into(vector<pair<int,int>> &dst,
const vector<pair<int,int>> &src)
{
static pair<int,int> buf[2 * B];
int na = dst.size(), nb = src.size();
int i = 0, j = 0, p = 0;
++merge_timer;
while ((i < na || j < nb) && p < B) {
pair<int,int> cand;
if (j == nb ||
(i < na && dst[i].first >= src[j].first + 1))
{
cand = dst[i++];
} else {
cand = {src[j].first + 1, src[j].second};
++j;
}
int s = cand.second;
if (seen[s] != merge_timer) {
seen[s] = merge_timer;
buf[p++] = cand;
}
}
dst.assign(buf, buf + p);
}
// cho truy vấn nặng
bool vis[MAXN];
int distv[MAXN];
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N >> M >> Q;
for (int i = 0; i < M; ++i) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
radj[v].push_back(u);
}
// 1) Khởi tạo best[u] = {(0, u)}
for (int u = 1; u <= N; ++u)
best[u].push_back({0, u});
// 2) Tiền xử lý (N+M)*B
for (int u = 1; u <= N; ++u) {
for (int v: adj[u]) {
merge_into(best[v], best[u]);
}
}
vector<int> busy_list, reach;
queue<int> bfsq;
while (Q--) {
int T, Y;
cin >> T >> Y;
busy_list.clear();
for (int i = 0; i < Y; ++i) {
int x; cin >> x;
ban[x] = true;
busy_list.push_back(x);
}
int answer = -1;
if (Y < B) {
// --- truy vấn nhẹ O(B) ---
for (auto &p: best[T]) {
if (!ban[p.second]) {
answer = p.first;
break;
}
}
} else {
// --- truy vấn nặng: BFS ngược + DP topo ngược ---
reach.clear();
bfsq.push(T);
vis[T] = true;
while (!bfsq.empty()) {
int v = bfsq.front(); bfsq.pop();
reach.push_back(v);
for (int u: radj[v]) {
if (!vis[u]) {
vis[u] = true;
bfsq.push(u);
}
}
}
// xử lý DP theo thứ tự giảm u (bởi S<E)
sort(reach.begin(), reach.end(), greater<int>());
answer = -1;
for (int u: reach) {
int best_len = ban[u] ? INT_MIN/2 : 0;
for (int v: adj[u]) {
if (vis[v])
best_len = max(best_len, distv[v] + 1);
}
distv[u] = best_len;
if (!ban[u] && distv[u] >= 0)
answer = max(answer, distv[u]);
}
// reset vis và distv chỉ với reach
for (int u: reach) {
vis[u] = false;
// distv[u] sẽ được ghi đè ở lần tiếp theo khi cần
}
}
cout << answer << "\n";
// clear ban flags
for (int x: busy_list) ban[x] = false;
}
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... |