luogu_P1983 车站分级

传送门: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;
}
View Code

 

posted @ 2019-10-21 10:11  Ryn_Honey  阅读(108)  评论(0编辑  收藏  举报