您的位置:首页 > 其它

Educational Codeforces Round 25 E. Minimal Labels 拓扑排序+逆向建图

2017-07-18 15:02 429 查看
E. Minimal Labels

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

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 n, m (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 3
1 2
1 3
3 2


output
1 3 2


input
4 5
3 1
4 1
2 3
3 4
2 4


output
4 1 2 3


input
5 4
3 1
2 1
2 3
4 5


output
3 1 2 4 5


题意:给你n个点,m条边的有向无环图,一条边u->v表示u的权值小于v的权值;求字典序最小的方案;

思路:反向建图,使得大的点的权值更大;类似与hdu 4857;

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define LL long long
#define pi (4*atan(1.0))
#define eps 1e-14
#define bug(x)  cout<<"bug"<<x<<endl;
const int N=1e5+10,M=2e6+10,inf=1e9+10;
const LL INF=1e18+10,mod=1e9+7;

vector<int>edge
;
int du
,ans
;
priority_queue<int>q;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
edge[v].push_back(u);
du[u]++;
}
for(int i=1;i<=n;i++)
if(!du[i])q.push(i);
int s=n;
while(!q.empty())
{
int x=q.top();
q.pop();
ans[x]=s--;
for(int i=0;i<edge[x].size();i++)
{
int v=edge[x][i];
du[v]--;
if(!du[v])q.push(v);
}
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: