反向拓扑排序

对于初始没有进行编号,且要求数字小的尽可能在前面
需要进行反向拓扑排序

真的看不懂
反正需要进行
邻接表优化
传送门
传送门

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 3e4+5;
int n,m,cnt;
bool mp[N][N];
int du[N],head[N];
int a[N];
struct P{
    int to,nxt;
}e[N];
void add(int u,int v){
    e[cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}
void topsort(){
    int k=n;
    priority_queue<int>q;
    for(int i=1;i<=n;i++) if(!du[i]) q.push(i);
    while(!q.empty()){
        int tmp=q.top();
        q.pop();
        a[tmp]=k--;
        for(int i=head[tmp];~i;i=e[i].nxt){
            int v=e[i].to;
            du[v]--;
            if(!du[v]) q.push(v);
        }
    }
    if(k!=0) printf("-1\n");
    else{
        for(int i=1;i<=n;i++)
            printf("%d%c",a[i],i==n?'\n':' ');
    }
}
void init(){
    memset(mp,0,sizeof(mp));
    memset(a,0,sizeof(a));
    memset(head,-1,sizeof(head));
    memset(du,0,sizeof(du));
    cnt=0;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        init();
        scanf("%d%d",&n,&m);
        while(m--){
            int x,y;
            scanf("%d%d",&x,&y);
            if(mp[x][y]==1) continue;//重边
            mp[x][y]=1,add(y,x);//反向边
            du[x]++;
        }
        topsort();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Emcikem/p/12013207.html

时间: 2024-10-18 00:25:57

反向拓扑排序的相关文章

HDU 4857 (反向拓扑排序 + 优先队列)

题意:有N个人,M个优先级a,b表示a优先于b,并且每个人有个编号的优先级,输出顺序. 思路来自:与PKU3687一样 在基本的拓扑排序的基础上又增加了一个要求:编号最小的节点要尽量排在前面:在满足上一个条件的基础上,编号第二小的节点要尽量排在前面:在满足前两个条件的基础上,编号第三小的节点要尽量排在前面--依此类推.(注意,这和字典序是两回事,不可以混淆.) 如图 1 所示,满足要求的拓扑序应该是:6 4 1 3 9 2 5 7 8 0. 图 1 一个拓扑排序的例子 一般来说,在一个有向无环图

逃生(HDU4857 + 反向拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题面是中文题面,就不解释题意了,自己点击链接去看下啦~这题排序有两个条件,一个是按给定的那个序列(即输入的u,v,优先级最高),一个是序号从小到大(优先级次之).正向的话由于这两个条件不好维护,所以就想着用反向拓扑排序来实现.首先记录每个节点的出度,然后用优先队列来维护顺序(使用默认的从大到小排序),最后反向输出即可. 代码实现如下: 1 #include <queue> 2 #includ

【HDOJ4857】【反向拓扑排序】

http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6665    Accepted Submission(s): 1950 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行.现

POJ3687 反向拓扑排序

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16032   Accepted: 4713 Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that: No two balls share

正向与反向拓扑排序的区别(hdu 1285 确定比赛名次和hdu 4857 逃生)

确定比赛名次 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 16   Accepted Submission(s) : 9 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比

HDU 4857 逃生 (反向拓扑排序 &amp; 容器实现)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4505    Accepted Submission(s): 1282 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排

HDU 4857 逃生(反向拓扑排序+优先队列)

( ̄▽ ̄)" //这题对序号输出有要求,较小的序号优先输出,所以用到优先队列 //优先队列是优先弹出值最大的,所以最后要反向输出结果,才是正确的output #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<cstdlib> #inc

hdu 4857 逃生【反向拓扑排序】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4857 题意:中文不解释 解法: input: 1 3 1 3 1 answer: 3 1 2 而不是 2 3 1 所以逆向建边 拓扑 代码: #include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> #include<ctype.h> #include<a

HDU-4857 逃生(反向拓扑排序 + 逆向输出)

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5703    Accepted Submission(s): 1671 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是