拓扑序列+dp思想
该题可以用邻接表存下每一个章节需要理解哪些章节,再利用dp思想找到答案
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N=2e5+10;
int d[N],f[N];//每个章节的需理解数、理解每章节需要的次数
vector<int> g[N];//存每个章节需要理解的各章节
int n;
int main()
{
int T;
cin>>T;
while(T--)
{
//初始化
for(int i=1;i<=n;i++)
{
g[i].clear();
f[i]=0;
d[i]=0;
}
cin>>n;
for(int i=1;i<=n;i++)
{
int k;cin>>k;
d[i]=k;
while(k--)
{
int x;
cin>>x;
g[x].push_back(i);
}
}
queue<int> q;
for(int i=1;i<=n;i++)
{
if(!d[i])q.push(i),f[i]=1;
}
while(q.size())
{
int t=q.front();
q.pop();
for(auto i:g[t])
{
d[i]--;
if(t>i)f[i]=max(f[i],f[t]+1);//如果当前章节要先理解一个比它大的章节则需判断是该点已经理解了还是要再读一遍
else f[i]=max(f[i],f[t]);//如果小则直接判断
if(d[i]==0)q.push(i);
}
}
int ans=0,ff=1;
for(int i=1;i<=n;i++)
{
ans=max(ans,f[i]);
if(d[i])ff=0;
}
if(ff==0)cout<<"-1"<<endl;
else cout<<ans<<endl;
}
return 0;
}