题意:
思路:
每本书之间很明显存在拓扑关系,由此想到拓扑排序。使用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;
}