题目
The Kingdom of Topcaria is planning a series of developmental projects to enhance its infrastructure. Each project has specific prerequisites that must be completed before the project can start. The Ministry of Development has asked you to help determine a feasible order in which all the projects can be completed.
You are given:
- 𝑛, the number of projects numbered from 11 to 𝑛.
- 𝑚, the number of prerequisite relationships between these projects.
- 𝐴 list of 𝑚 pairs, where each pair (𝑎,𝑏) indicates that project 𝑎 must be completed before project 𝑏 can start.
Your task is to determine an order in which all the projects can be completed. If it is impossible to complete all projects due to a cyclic dependency, output “IMPOSSIBLE”. If there are multiple valid orders, please output any the lexicographically smallest one.
Input
The first line contains two integers n𝑛 and 𝑚 — the number of projects and the number of prerequisite relationships. The next m𝑚 lines each contain two integers 𝑎 and 𝑏 — a prerequisite pair indicating that project 𝑎 must be completed before project 𝑏.
Technical Specification
- 1≤𝑛≤10^5
- 0≤𝑚≤2×10^5
- 𝑎,𝑏∈{1,2,…,𝑛}
- 𝑎≠𝑏
- No duplicate pairs are given.
Output
If it is not possible, output “IMPOSSIBLE”. If it is possible to complete all projects, output a single line with 𝑛 integers — a valid order of project completions. If there are multiple possible orders, output the lexicographically smallest one. An order is lexicographically smaller than another order if at the first position where they differ, the project number on the first order is smaller than the number on the second order.
Examples
input
5 5
1 2
2 3
2 4
2 5
3 4
output
1 2 3 4 5
input
5 4
1 2
2 3
3 1
5 4
output
IMPOSSIBLE
题解
首先使用Tarjan算法求强通分量来求解是否存在正环,如果存在则输出"IMPOSSIBLE"
接着使用小根堆输出拓扑排序的结果,保证字典序最小。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int N = 1e5 + 10, M = N << 1;
int n, m;
int ne[M], idx, e[M], h[M];
stack<int> stk;
bool st[N];
int dfn[N], low[N], timestamp;
int id[N], sz[N], scc_cnt;
int in[N], out[N];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++timestamp;
stk.push(u), st[u] = 1;
for (int i = h[u]; ~i; i = ne[i])
{
int v = e[i];
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (st[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u])
{
++scc_cnt;
int y;
do {
y = stk.top(); stk.pop();
id[y] = scc_cnt;
st[y] = 0;
sz[scc_cnt]++;
} while (y != u);
}
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
while (m--)
{
int a, b;
cin >> a >> b;
add(a, b);
in[b]++, out[a]++;
}
for (int i = 1; i <= n; i++)
if (!dfn[i])
tarjan(i);
for (int i = 1; i <= n; i++)
for (int j = h[i]; ~j; j = ne[j])
{
int k = e[j];
int a = id[i], b = id[k];
if (a == b) {
puts("IMPOSSIBLE");
return 0;
}
}
vector<int> ans;
priority_queue<int, vector<int>, greater<int>> heap;
for (int i = 1; i <= n; i++)
if (!in[i])
heap.push(i);
while (!heap.empty())
{
int t = heap.top();
heap.pop();
ans.push_back(t);
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if (--in[j] == 0)
{
heap.push(j);
}
}
}
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << ' ';
return 0;
}