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

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 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 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[N];
int du[N],ans[N];
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;
}
原文地址:https://www.cnblogs.com/jhz033/p/7200538.html