題意:
思路:
每本書之間很明視訊記憶體在拓撲關係,由此想到拓撲排序。使用set對圖進行拓撲排序,將閱讀次數小的放在前面,若閱讀次數相同則按照閱讀章節編號排序。假設第 x 章在第
y 章理解之後就能理解,若 x 大於 y 則本次閱讀就可以理解 x 章,否則需要下一次才能理解第 x 章。
code:
#include <bits/stdc++.h>
#include<bits/extc++.h>
using namespace __gnu_pbds;
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using PII = pair<int, int>;
const int inf = 0x3f3f3f3f;
const i64 INF = 0x3f3f3f3f3f3f3f3f;
#define Z cout << "\n"
#define lb lower_bound
#define ub upper_bound
#define D(x) cerr << #x << ": " << (x) << "\n"
#define DV(v) cerr<<#v<<": ";for(int i=0;i<(v).size();i++)cerr<<((v)[i])<<",";cerr<<"\n"
#if 0
#define int i64
#endif
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<vector<int>>g(n + 5);
vector<int>ld(n + 5);
for (int i = 1; i <= n; i++) {
int m;
cin >> m;
for (int j = 1; j <= m; j++) {
int x; cin >> x;
g[x].push_back(i);
ld[i]++;
}
}
auto topsort = [&] ()->PII {
int res = 0, tot = 0;
multiset<PII>se;
for (int i = 1; i <= n; i++) {
if (ld[i] == 0)se.insert({ 1,i });
}
while (se.size()) {
PII q = *se.begin();
se.erase(se.begin());
tot++;
res = max(res, q.first);
for (auto v : g[q.second]) {
if (--ld[v] == 0) {
if (v > q.second) {
se.insert({ q.first,v });
}
else {
se.insert({ q.first + 1,v });
}
}
}
}
return { res,tot };
};
auto [u, v] = topsort();
if (v < n)cout << -1 << "\n";
else cout << u << "\n";
}
return 0;
}