版权声明: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;
}