车站分级

【题目描述】

一条单向的铁路线上,依次有编号为1、2、······、n的n个火车站。每个火车站都有一个级别,最低为1级。

现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:

如果这趟车次停靠了火车站x,则始发站、终点站之间所有级别大于等于火车站x的都必须停靠(注意:起始站和终点站自然也算作事先已知需要停靠的站点)。

例如,下表是5趟车次的运行情况。其中,前4趟车次均满足要求,而第5趟车次由于停靠了3号火车站(2级)却未停靠途经的6号火车站(亦为2级)而不满足要求。

现有m趟车次的运行情况(全部满足要求),试推算这n个火车站至少分为几个不同的级别。

【输入描述】

第一行包含2个正整数n、m,用一个空格隔开;

第i+1行(1 ≤ i ≤ m)中,首先是一个正整数si(2 ≤ si ≤ n),表示第i趟车次有si个停靠站,接下来有si个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。

【输出描述】

输出只有一行,包含一个正整数,即n个火车站最少划分的级别数。

【输入样例】

样例1:

9 2

4 1 3 5 6

3 3 5 6

 

样例2:

9 3

4 1 3 5 6

3 3 5 6

3 1 5 9

【输出样例】

样例1:

2

 

样例2:

3

对于20%的数据,1 ≤ n,m ≤ 10;

对于50%的数据,1 ≤ n,m ≤ 100;

对于100%的数据,1 ≤ n,m ≤ 1000。

 

都说用拓扑排序,但记忆化搜索依旧老当益壮:

源代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,i[1001],f[1001],Next[1001][1001];
bool Vis[1001],Mark[1001][1001];
int DFS(int t)
{
    if (f[t])
      return f[t];
    if (!Next[t][0])
      return f[t]=1;
    for (int a=1;a<=Next[t][0];a++)
    {
        DFS(Next[t][a]);
        if (f[t]<f[Next[t][a]]+1)
          f[t]=f[Next[t][a]]+1;
    }
    return f[t];
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int a=1;a<=m;a++)
    {
        int N;
        scanf("%d",&N);
        for (int b=1;b<=N;b++)
        { 
            scanf("%d",&i[b]);
            Vis[i[b]]=true;
        }
        for (int b=i[1];b<=i[N];b++)
          if (!Vis[b])
            for (int c=1;c<=N;c++)
              if (!Mark[b][i[c]])
              {
                Mark[b][i[c]]=true;
                Next[b][++Next[b][0]]=i[c];
              }
        for (int b=i[1];b<=i[N];b++)
          Vis[b]=false;
    }
    int ans=0;
    for (int a=1;a<=n;a++)
      if (!f[a])
        ans=max(ans,DFS(a));
    printf("%d",ans);
    return 0;
}

 

posted @ 2016-08-26 14:56  前前前世。  阅读(291)  评论(0编辑  收藏  举报