题解 | 2023 年牛客多校第三场 J 题 Fine Logic
Fine Logic
https://ac.nowcoder.com/acm/contest/57357/J
题意:给定 个点和 对偏序关系 ,构造最少的排列数目 ,使得在这 个排列中至少有一个排列满足 。。
解法:数据范围过于庞大意味着 必然不大。其实很容易发现一种任意情况下都成立的方案:,一个排列是 ,另一个排列是 。因为 的情况在第一个排列中, 在第二个排列中。
考虑什么时候满足 。如果 ,则必然存在一个拓扑序列。考虑依照 建图,即必须访问完 才能访问 。如果该 DAG 有拓扑序,那么这个排列就是合法的。否则则按 的方案构造。
#include <bits/stdc++.h>
using namespace std;
const int N = 1000000;
int in[N + 5];
vector<int> G[N + 5];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i <= m; i++)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
in[v]++;
}
queue<int> q;
for (int i = 1; i <= n; i++)
if (!in[i])
q.push(i);
vector<int> ans;
while (!q.empty())
{
int tp = q.front();
q.pop();
ans.push_back(tp);
for (auto x : G[tp])
{
in[x]--;
if (!in[x])
q.push(x);
}
}
if (ans.size() == n)
{
printf("1\n");
for (auto x : ans)
printf("%d ", x);
}
else
{
printf("2\n");
for (int i = 1; i <= n; i++)
printf("%d ", i);
printf("\n");
for (int i = n; i >= 1; i--)
printf("%d ", i);
printf("\n");
}
return 0;
}