思路
我们让没有被停靠的站与被停靠的站连一条单向边,然后正常来一波拓扑排序。
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int pa[100010],now[100010],ls[100010],dl[100010],d[100010],v[100010],map[1010][1010];
int n,m,pas,tot,js[100010];
struct node
{
int y,next;
}a[1000010];
void add(int x,int y)
{
a[++tot]=(node){
y,ls[x]};
ls[x]=tot;
}
void tp()
{
int hd=0,tl=0;
for(int i=1; i<=n; i++)
if(d[i]==0)
dl[++tl]=i,v[i]=1,js[i]=1;
while(hd<tl)
{
hd++;
int y=dl[hd];
for(int i=ls[y]; i; i=a[i].next)
{
int yy=a[i].y;
if(v[yy]==1)
continue;
d[yy]--;
if(d[yy]==0)
{
js[yy]=js[y]+1;
dl[++tl]=yy;
v[yy]=1;
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1; i<=m; i++)
{
memset(now,0,sizeof(now));
scanf("%d",&pas);
for(int j=1; j<=pas; j++)
{
scanf("%d",&pa[j]);
now[pa[j]]=1;
}
for(int j=pa[1]; j<=pa[pas]; j++)
{
if(now[j]==1)
continue;
for(int k=1; k<=pas; k++)
map[j][pa[k]]=1; //中转站,减少邻接表的调用,以防RE
}
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(map[i][j]==1)
{
add(i,j);
d[j]++;
}
tp();
int ans=0;
for(int i=1; i<=n; i++)
ans=max(ans,js[i]);
cout<<ans;
return 0;
}