A. Book
题意:
给出n本书,对于每本书给出ki个数,你能理解第i本书当且仅当你全部读过这ki本书,问读多少轮可以理解全部的书,1轮指1-n都读一遍。若无法理解 则输出-1。
思路:
不难想到拓扑排序,先把入度为0的所有点加入队列,扫描从队列中的点u出发的边指向的点v,
dp[v] = max(dp[v], dp[u] + (u > v)),注意每次遍历都减少v点的入度,若入度为0则加入。
// Decline is inevitable, romance will last forever.
#include <bits/stdc++.h>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
#define P 998244353
//#define int long long
const int maxn = 2e5 + 10;
const int maxm = 3e5*4 + 10;
int in[maxn];
int dp[maxn];
queue<int> q;
vector<int> edge[maxn];
void solve() {
int n;
cin >> n;
for(int i = 1; i <= n; i++)
edge[i].clear();
mst(in, 0);
mst(dp, -1);
for(int i = 1; i <= n; i++) {
int k;
cin >> k;
for(int j = 1; j <= k; j++) {
int u;
cin >> u;
edge[u].push_back(i);
in[i]++;
}
}
for(int i = 1; i <= n; i++)
if(!in[i]) {
q.push(i);
dp[i] = 1;
}
while(!q.empty()) {
int u = q.front();
q.pop();
for(auto v : edge[u]) {
in[v]--;
dp[v] = max(dp[v], dp[u] + (u > v));
if(!in[v])
q.push(v);
}
}
int ans = -1;
for(int i = 1; i <= n; i++) {
if(in[i]) {
cout << -1 << '\n';
return;
}
ans = max(ans, dp[i]);
}
cout << ans << '\n';
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
// int T; scanf("%d", &T); while(T--)
int T; cin >> T; while(T--)
solve();
return 0;
}