p1242 字典序最小的拓扑序

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84435758

题目

描述 Description
给定一个有N个节点的有向图(编号为0~N-1),求其拓扑排序的最小字典序。
输入格式 Input Format
第一行两个整数 N和M,表示图有N个点,M条边。
接下来M行,2个整数ui和vi,表示ui到vi有条有向边。
输出格式 Output Format
N个用空格隔开的整数,表示拓扑序列。
样例输入 Sample Input

3 2
0 2
1 2
样例输出 Sample Output

0 1 2
时间限制 Time Limitation
1s
注释 Hint
对于60%的数据,N ≤ 1, 000。
对于100%的数据,N ≤ 100, 000,M ≤ 1, 000, 000。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
	ll f=1,num=0;
	char ch=getchar();
	while (ch<'0'||ch>'9') { if (ch=='-') f=-1;ch=getchar(); }
	while (ch>='0'&&ch<='9') num=(num<<1)+(num<<3)+ch-'0',ch=getchar();
	return num*f;
}
ll n,m,tot;
ll ver[1000010],Next[1000010],head[100010],ans[100010],v[100010];
void add(int x,int y)
{
	ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
}
void topsort()
{
	priority_queue<int,vector<int>,greater<int> >q;
	for (int i=0;i<n;i++) if (!v[i]) q.push(i);
	while (!q.empty())
	{
		int x=q.top();
		q.pop();
		ans[++tot]=x;
		for (int i=head[x];i;i=Next[i])
		{
			int y=ver[i]; 
			--v[y];
			if (!v[y]) q.push(y);
		}
	}
}
int main()
{
	n=read(),m=read();
	for (int i=1;i<=m;i++)
	{
		ll x=read(),y=read();
		add(x,y); 
		++v[y];
	}
	tot=0;
	topsort();
	for (int i=1;i<=n;i++)
		cout<<ans[i]<<' ';
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84435758