0
点赞
收藏
分享

微信扫一扫

CF1573C. Book(拓扑排序 最长路)


​​linkkkk​​​ 题意:
每个书有页,每页都有前置页,学会这些前置页你才能够学会这页。每次阅读都是从的顺序,问需要阅读几次才能够学完这本书。
思路:
对于每页和他的前置页,建图,表示学会必须要学会,如果说的话,权值为,表示两者在同一轮阅读里学会;否则,权值为,表示下一轮才能够学会。
求最长路就是答案。
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn=2e5+10,inf=0x3f3f3f3f;

int h[maxn],e[maxn],ne[maxn],w[maxn],idx;
int din[maxn],dp[maxn],n;
vector<int>top;

void add(int u,int v,int ww){
e[idx]=v,ne[idx]=h[u],w[idx]=ww,h[u]=idx++;
}

bool topsort(){
top.clear();
queue<int>q;
for(int i=1;i<=n;i++)
if(!din[i]) q.push(i);
while(!q.empty()){
int t=q.front();q.pop();
top.push_back(t);
for(int i=h[t];~i;i=ne[i]){
int j=e[i];
if(!--din[j]) q.push(j);
}
}
return top.size()==n;
}

int main(){
int _;cin>>_;
while(_--){
memset(h,-1,sizeof h);
idx=0;
memset(din,0,sizeof din);
cin>>n;
for(int i=1;i<=n;i++){
int m;cin>>m;
for(int j=1;j<=m;j++){
int x;cin>>x;
if(x>i) add(x,i,1);
else add(x,i,0);
din[i]++;
}
}
if(!topsort()) puts("-1");
else{
int ans=0;
memset(dp,0,sizeof dp);
for(int now:top){
for(int i=h[now];~i;i=ne[i]){
int j=e[i];
dp[j]=max(dp[j],dp[now]+w[i]);
}
}
for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans+1<<"\n";
}
}
return 0;
}
/*
5
4
1 2
0
2 1 4
1 2
5
1 5
1 1
1 2
1 3
1 4
5
0
0
2 1 2
1 2
2 2 1
4
2 2 3
0
0
2 3 2
5
1 2
1 3
1 4
1 5
0

*/


举报

相关推荐

0 条评论