2024 ICPC Asia Taiwan Online Programming Contest K. Kingdom‘s Development Plan (SCC + 拓扑排序字典序输出)

题目

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值