正题
题目链接:https://www.luogu.org/problemnew/show/P1983
题目大意
一个辆车会一个一个值xxx,如果等级大于等于xxx的车站都会停靠(包括起点和终点)。给每辆车的停靠点,求至少要将车站分多少级。
解题思路
对于一辆车,若一个点他经过了却没有停靠,那么这个点比所有的停靠点的等级都要低。然后根据这个关系连边,然后记忆化dfsdfsdfs。时间复杂度O(nm2)O(nm^2)O(nm2),边比较多,建议用邻接矩阵。但是是14\frac{1}{4}41常数,所以可以过。
可以优化成O(nm)O(nm)O(nm)的。对于没辆车,我们的边数是O(nm)O(nm)O(nm)条的密集图,所以我们可以建立一个虚点,然后将边数变为O(n+m)O(n+m)O(n+m)条。
codecodecode
#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);
}