车站分级

P1983 [NOIP2013 普及组] 车站分级 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  • tupo[i][j]==1代表tupo图中i和j之间有一条边,也就是i的级别比j小
  • 对于每趟车次,遍历这趟车次的起点到终点中的每一个点,对于不是停靠点的点(也就是路过的点)由题意这些点的级别肯定比停靠点的级别低,那么应该把所有非停靠点与停靠点连边,对停靠点入度+1
  • tupo过程要求出分了多少层,所分的层数就是答案
  • 对每次tupo过程,把入度为0且没有入过栈的点入栈,然后每取出栈里的一个元素,把所有与他相连接的点删边删点
// https://www.luogu.com.cn/problem/P1983
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 1005
// 9 2
// 4 1 3 5 6
// 3 3 5 6
int n, m, nums, station[MAX], tupo[MAX][MAX], dutt[MAX];
bool is[MAX];
void build()
{
    cin >> n >> m;
    while (m--)
    {
        memset(is, 0, sizeof(is));
        scanf("%d", &nums);
        for (int i = 1; i <= nums; i++)
        {
            scanf("%d", station + i);
            is[station[i]] = true;
        }
        for (int i = station[1]; i <= station[nums]; i++)
        {
            if (!is[i])
                for (int j = 1; j <= nums; j++)
                {
                    if (!tupo[i][station[j]])
                    {
                        tupo[i][station[j]] = 1;
                        dutt[station[j]]++;
                    }
                }
        }
    }
}
stack<int> S;
int ans;
bool flag[MAX];
void tu()
{
    while (true)
    {
        for (int i = 1; i <= n; i++)
        {
            if (!dutt[i] && !flag[i])
            {
                S.push(i);
                flag[i] = true;
            }
        }
        if (S.empty())
            break;
        while (!S.empty())
        {
            int t = S.top();
            S.pop();
            for (int i = 1; i <= n; i++)
            {
                if (tupo[t][i])
                {
                    tupo[t][i] = 0;
                    dutt[i]--;
                }
            }
        }
        ans++;
    }
    printf("%d", ans);
}
int main()
{
    build();
    tu();
}

 

posted on 2022-08-08 14:32  樵风  阅读(133)  评论(0)    收藏  举报