CF-Educational-25 E-Minimal Labels (拓扑排序,字典序)

来源:互联网 发布:centos下载apache教程 编辑:程序博客网 时间:2024/05/16 06:35

You are given a directed acyclic graph with n vertices and m edges. There are no self-loops or multiple edges between any pair of vertices. Graph can be disconnected.

You should assign labels to all vertices in such a way that:

  • Labels form a valid permutation of length n — an integer sequence such that each integer from 1 to n appears exactly once in it.
  • If there exists an edge from vertex v to vertex u then labelv should be smaller than labelu.
  • Permutation should be lexicographically smallest among all suitable.

Find such sequence of labels to satisfy all the conditions.

Input

The first line contains two integer numbers nm (2 ≤ n ≤ 105, 1 ≤ m ≤ 105).

Next m lines contain two integer numbers v and u (1 ≤ v, u ≤ n, v ≠ u) — edges of the graph. Edges are directed, graph doesn't contain loops or multiple edges.

Output

Print n numbers — lexicographically smallest correct permutation of labels of vertices.

Examples
input
3 31 21 33 2
output
1 3 2 
input
4 53 14 12 33 42 4
output
4 1 2 3 
input
5 43 12 12 34 5
output
3 1 2 4 5 
此题是拓扑排序裸题,但字典序要注意。取出节点时要先取出编号大的节点打上编号大的标签(反图),如果直接从小到大找入度为零的点然后编号的话会有反例


如图,如果从小到大讨论的话答案是     3    1     2    但显然正解是       2       3       1

附我naive的wa代码

#include<cstdio>#include<iostream>#include<queue>#include<algorithm>#define N 2222222using namespace std;int n,m,d[N],tot,ans[N];int TOT,EN[N],NE[N],LA[N];void ADD(int x,int y){TOT++;EN[TOT]=y;NE[TOT]=LA[x];LA[x]=TOT;}priority_queue<int,vector<int>,greater<int> >q;int main(){int i,j,x,y;cin>>n>>m;for(i=1;i<=m;i++){scanf("%d%d",&x,&y);d[y]++;ADD(x,y);}for(i=1;i<=n;i++)if(d[i]==0)q.push(i);while(!q.empty()){x=q.top();q.pop();ans[x]=++tot;for(i=LA[x];i;i=NE[i]){y=EN[i];if(d[y]>0){d[y]--;    if(d[y]==0)q.push(y);}}}for(i=1;i<=n;i++)printf("%d ",ans[i]);}


附ac代码

#include<cstdio>#include<iostream>#include<queue>#include<algorithm>#define N 222222using namespace std;int n,m,d[N],tot,ans[N];int TOT,EN[N],NE[N],LA[N];void ADD(int x,int y){TOT++;EN[TOT]=y;NE[TOT]=LA[x];LA[x]=TOT;}priority_queue<int>q;int main(){int i,j,x,y;cin>>n>>m;for(i=1;i<=m;i++){scanf("%d%d",&x,&y);d[x]++;ADD(y,x);}for(i=1;i<=n;i++)if(d[i]==0)q.push(i);tot=n;while(!q.empty()){x=q.top();q.pop();ans[x]=tot--;for(i=LA[x];i;i=NE[i]){y=EN[i];if(d[y]>0){d[y]--;    if(d[y]==0)q.push(y);}}}for(i=1;i<=n;i++)printf("%d ",ans[i]);}


原创粉丝点击