#include<bits/stdc++.h>
using namespace std;

/*
最坏情况下有1000趟火车,每趟1000个点,500个停靠,500个不停靠站
不停站的点 和 停站的点 都链接一条边:  500*500*1000 = 2.5 * 10^8
*/
const int N = 2010, M = 1e6 + 20; //一趟车次需要一个虚拟点,每次最多1000条边

int n, m;
int e[M], ne[M], w[M], h[N], idx;
int dist[N];
bool st[N];
int q[N], d[N]; //d数组是统计每个点的入度的个数
int res;

void add(int a, int b, int c)
{
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx ++;
    d[b] ++;
}

void topsort()
{
    int hh = 0, tt = -1;
    for(int i = 1; i <= n + m; i++)
    {
        if(!d[i]) q[++tt] = i;
    }

    while(hh <= tt) {
        int t = q[hh++];
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(--d[j] == 0)
                q[++tt] = j;
        }
    }
}


int main()
{
    cin >> n >> m;
    memset(h, -1, sizeof h);
    for(int i = 1; i <= m; i++)
    {
        memset(st, 0, sizeof st);
        int cnt;
        cin >> cnt;
        int start = n, end = 1;
        while(cnt --)
        {
            int stop;
            cin >> stop;
            start = min(start, stop);
            end = max(end, stop);
            st[stop] = true;
        }

        int v = i + n; //虚拟点,是从n+1开始编号
        for(int j = start; j <= end; j++)
            if(st[j]) add(v, j, 1);
            else add(j, v, 0);
    }

    topsort();

    for(int i = 1; i <= n; i++) dist[i] = 1;
    
    for(int i = 0; i < n + m; i++) // n+m个点
    {
        int t = q[i];
        cout << t << ":";
        for(int k = h[t]; k != -1; k = ne[k])
        {
            int j = e[k];
            dist[j] = max(dist[j], dist[t] + w[k]);

            cout << "j=" << j << " " << dist[j] << endl;
        }
        cout << "-------------" << endl;
    }

    // for(int i = 1; i <= n + m; i++)
    //     cout << dist[i] << " ";
    // cout << endl;

    for(int i = 1; i <= n; i++)
        res = max(res, dist[i]);
    
    cout << res << endl;
    
    return 0;
}

0 条评论

目前还没有评论...