LG1983 「NOIP2013」车站分级 拓扑排序

问题描述

LG1983


题解

考虑建立有向边\((a,b)\),代表\(a\)\(b\)低级。

于是枚举每一辆车次经过的车站\(x \in [l,r]\),如果不是车辆停靠的车站,则从\(x\)向每个停靠了的车站连边。

拓扑排序,建立分层图,搞出最大的层数即可。


\(\mathrm{Code}\)

#include
using namespace std;



template 
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-'){
        fh=-1;ch=getchar();
    }
    else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    x*=fh;
}

const int maxn=1007;
const int maxm=1000007;
int k,a[maxn],ina[maxn];
bool exist[maxn][maxn];
int n,m;
int Head[maxn],Next[maxm],to[maxm],tot=1;

int rd[maxn];

void add(int x,int y){
    to[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
}

int dep[maxn],ans=1;

void toposort(){
    queueq;
    for(int i=1;i<=n;i++){
        if(!rd[i]){
            q.push(i);dep[i]=1;
        }
    }
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=Head[x];i;i=Next[i]){
            int y=to[i];--rd[y];
            if(!rd[y]){
                q.push(y);dep[y]=dep[x]+1;
                ans=max(dep[y],ans);
            }
        }
    }
}

int main(){
    read(n);read(m);
    for(int i=1;i<=m;i++){
        read(k);memset(ina,0,sizeof(ina));
        for(int j=1;j<=k;j++){
            read(a[j]);ina[a[j]]=1;
        }
        for(int j=a[1];j<=a[k];j++){
            if(ina[j]) continue;
            for(int p=1;p<=k;p++){
                if(!exist[j][a[p]]){
                    ++rd[a[p]];add(j,a[p]);
                    exist[j][a[p]]=1;
                }
            }
        }
    }
    toposort();
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/liubainian/p/11516677.html

你可能感兴趣的:(LG1983 「NOIP2013」车站分级 拓扑排序)