[拓扑序] Educational Codeforces Round 25 825E. Minimal Labels

来源:互联网 发布:淘宝水晶店哪家是真的 编辑:程序博客网 时间:2024/06/04 22:21

题意

戳这里

题解

This problem is usually called “Topological labelling”. Though it’s pretty common problem, we decided that it might be educational to some of participants. —cf官方题解

我好菜啊……
这个要反着贪心,反向建图,从n1 分配标签,每次分配给下标最大的。
正着搞是不对的,比如这个例子

4 22 34 1

感性理解一下,正着搞有点只顾眼前利益的感觉,把小数字往前放,没有考虑到对后面的影响是否是好的。

#include<cstdio>#include<algorithm>#include<vector>#include<queue>using namespace std;const int maxn=10000005, maxe=maxn;priority_queue< int > _heap;int n,m,d[maxn],now,a[maxn];int fir[maxn],nxt[maxe],son[maxe],tot;void add(int x,int y){    son[++tot]=y; nxt[tot]=fir[x]; fir[x]=tot;}int main(){    //freopen("E.in","r",stdin);    //freopen("E.out","w",stdout);    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        int x,y; scanf("%d%d",&x,&y);        add(y,x); d[x]++;    }    for(int i=1;i<=n;i++) if(!d[i]) _heap.push(i);    now=n;    while(!_heap.empty()){        int x=_heap.top(); _heap.pop();        a[x]=now--;        for(int j=fir[x];j;j=nxt[j]){            if((--d[son[j]])==0) _heap.push(son[j]);        }    }    for(int i=1;i<=n;i++) printf("%d ",a[i]);    return 0;}