正题
题目链接:https://www.luogu.org/problemnew/show/P1983
题目大意
一个辆车会一个一个值x,如果等级大于等于x的车站都会停靠(包括起点和终点)。给每辆车的停靠点,求至少要将车站分多少级。
解题思路
对于一辆车,若一个点他经过了却没有停靠,那么这个点比所有的停靠点的等级都要低。然后根据这个关系连边,然后记忆化dfs。时间复杂度O(nm2),边比较多,建议用邻接矩阵。但是是41常数,所以可以过。
可以优化成O(nm)的。对于没辆车,我们的边数是O(nm)条的密集图,所以我们可以建立一个虚点,然后将边数变为O(n+m)条。
code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1050;
int ans,n,m,a[2*N][2*N],f[N];
bool v[N];
int dfs(int x){
if(f[x]) return f[x];
for (int i=1;i<=n+m;i++)
if(a[x][i]) f[x]=max(f[x],dfs(i));
if(x>n) f[x]--;
return ++f[x];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int t,x,star,end;
memset(v,0,sizeof(v));
scanf("%d",&t);
for(int j=1;j<=t;j++){
scanf("%d",&x);
a[x][n+i]=1;v[x]=1;
if(j==1) star=x;
if(j==t) end=x;
}
for(int j=star;j<=end;j++){
if(v[j]) continue;
a[n+i][j]=1;
}
}
for(int i=1;i<=n;i++)
ans=max(ans,dfs(i));
printf("%d",ans);
}