Description
一条单向的铁路线上,依次有编号为 1, 2, ..., n 的 n 个火车站。每个火车站都有一个级别,最低为 1 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站 x 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)
例如,下表是 5 趟车次的运行情况。
![]()
其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求。
Input
第一行包含 2 个正整数 n, m,用一个空格隔开。
第 i + 1 行(1 ≤ i ≤ m)中,首先是一个正整数 si(2 ≤ si ≤ n),表示第 i 趟车次有 si 个停靠站;接下来有 si 个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。
Output
输出只有一行,包含一个正整数,即 n 个火车站最少划分的级别数。
9 2 4 1 3 5 6 3 3 5 6 9 3 4 1 3 5 6 3 3 5 6 3 1 5 9
2 3
Hi仔细理解题意,要使得每一条线路中都没有错误的车次,我们用图来表示车次表,车站与车站之间的连接表示低等级指向高等级,将图进行拓扑排序进行分层分级,就可以得出最小的等级数。
#include<stdio.h>
#include<string.h>
int map1[1005][1005];
int main()
{
int i,j,rudu[1005],n,m,sumuse,che[1005],useche[1005],lenche,use[1005];
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(rudu,0,sizeof(rudu));
memset(use,0,sizeof(use));
memset(map1,0,sizeof(map1));
memset(useche,0,sizeof(useche));
sumuse=n;
for(int i=1;i<=m;i++)
{
memset(useche,0,sizeof(useche));
scanf("%d",&lenche);
for(int j=1;j<=lenche;j++)
{
scanf("%d",&che[j]);
useche[che[j]]=1;
}
for(int k=che[1];k<che[lenche];k++)
{
if(useche[k]==0)
{
for(int j=1;j<=lenche;j++)
map1[k][che[j]]=1;
}
}
}
for(int j=1;j<=n;j++)
{
int tem=0;
for(int i=1;i<=n;i++)
{
tem+=map1[i][j];
}
rudu[j]=tem;
}
/*for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",map[i][j]);
}
printf("\n");
}
for(int i=1;i<=n;i++)
{
printf("%d %d\n",i,rudu[i]);
}*/
int ans=0;
int ansn=0,inq[1005],qu[1001];
memset(inq,0,sizeof(inq));
memset(qu,0,sizeof(qu));
while(1)
{
int top=0;
for(int j=1;j<=n;j++)
{
if(!rudu[j]&&!inq[j])
{
qu[++top]=j;
inq[j]=1;
}
}
if(!top)
break;
for(int i=1;i<=top;i++)
{
for(int j=1;j<=n;j++)
{
if(map1[qu[i]][j]==1)
{
map1[qu[i]][j]=0;
rudu[j]--;
}
}
}
ans++;
}
printf("%d\n",ans);
}
return 0;
}