noip普及组2013 车站分级(luogu P1983)

原题链接:https://www.luogu.org/problem/show?pid=1983

题目大意:每个车站有一个权值,每一车次始发站与终点站之间如果有不停靠的点,那么它的权值一定比停靠的点的权值都要小。

处理完m条线路后,能够得到一系列的大小关系,于是就可以通过拓扑排序求出结果。

几个需要注意的地方:有的边可能已经被加过一次,所以最好用邻接矩阵存边,避免点的度数被重复加。

 

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; 
void read(int &y)
{
    y=0;char x=getchar();
    while(x<'0'||x>'9') x=getchar();
    while(x>='0'&&x<='9')
    {
        y=y*10+x-'0';
        x=getchar();
     } 
}
int n,m,x,ans,top;
int p[1005],d[1005],l[1005];
int e[1005][1005],st[1005];
bool b[1005],vis[1005];
int main()
{
    read(n);read(m);
    for(int i=1;i<=m;i++)
    {
        memset(b,0,sizeof(b));
        read(x);
        for(int j=1;j<=x;j++)
        {
            read(p[j]);
            b[p[j]]=1;
        }
        for(int j=p[1];j<=p[x];j++)
        {
            if(b[j]!=0) continue;
            for(int k=1;k<=x;k++)
            {
                if(e[j][p[k]]!=0) continue;
                e[j][p[k]]=1;
                d[p[k]]++;
            }
        }
    }
    top=0;
    for(int i=1;i<=n;i++)
    {
        if(d[i]==0)
        {
            st[++top]=i;
            l[i]=1;
        }
    }
    for(int i=1;i<=top;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(e[st[i]][j]==0) continue;
            e[st[i]][j]=0;
            d[j]--;
            if(d[j]==0)
            {
                l[j]=l[st[i]]+1;
                ans=max(ans,l[j]);
                st[++top]=j;
            }
        }
    }
    printf("%d",ans);
    return 0;
} 

 

posted @ 2017-10-24 09:42  Excim  阅读(177)  评论(0编辑  收藏  举报