p1242 字典序最小的拓撲序
阿新 • • 發佈:2018-11-24
題目
描述 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;
}