传送门:https://www.luogu.org/problem/P1983
第一种做法:(把我气炸了!!!
topsort。
把每辆火车路上不停车的点向的停车的点连单向边,最后拓扑排序即可
NO CODE,我TLE飞了!!!TAT 他们一边就AC了 QWQ 就我菜TAT
第二种做法:
记搜+虚点
第一种做法中你会发现,建的边这么多,不会炸吗? 没错我的会炸,他们的没炸QWQ
所以我们可以重新建一个点,让所有不停车的点向那个虚点连边,发现每个点只需要连一次,非常划算有没有。再从虚点想那些停车的点连一条边就把图建完了。
话说我刚打完建图,紧接着写了个topsort,然后 听取WA声一片.jpg 我怎么这么难。(本蒟蒻不清楚不理解不明白为什么不能topsort,可能这是个愚蠢的问题,但我真的不会啊TAT
翻开题解发现记搜,好的写上,然后水过去了.......
#include<cstdio> #include<queue> #define R register using namespace std; template <typename T> inline void read(T &x){ x=0;T flag=1;char c; c=getchar(); while(c<'0'||c>'9'){ if(c=='-') flag=-1; c=getchar(); } while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+c-48; c=getchar(); } x*=flag; } template <typename T> inline void cmax(T &x,T y){ if(x<y) x=y; } template <typename T> inline void cmin(T &x,T y){ if(x>y) x=y; } bool v[10010][10100]; int tot,head[100100],ver[10101000],nex[10100010]; inline void add(int x,int y){ ver[++tot]=y;nex[tot]=head[x];head[x]=tot; } int n,m,stop[1010][1010],ans; int d[120100]; queue<int> q; inline void dfs(int x){ if(d[x]) return; for(R int i=head[x];i;i=nex[i]){ if(!d[ver[i]]) dfs(ver[i]); cmax(d[x],d[ver[i]]+1); } if(x>n) d[x]--; cmax(ans,d[x]); } int main (){ read(n),read(m); for(R int i=1;i<=m;i++){ read(stop[i][0]); for(R int j=1,k=1;j<=stop[i][0];j++){ read(stop[i][j]);add(n+i,stop[i][j]); if(j>=2){ for(;k<stop[i][j];k++){ add(k,n+i); } } k=stop[i][j]+1; } } for(R int i=1;i<=n;i++){ if(!d[i]) dfs(i); } printf("%d",ans+1); return 0; }