车站分级
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();
}
浙公网安备 33010602011771号