码迷,mamicode.com
首页 > 编程语言 > 详细

反向拓扑排序

时间:2019-12-09 21:20:09      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:size   php   ace   can   编号   mem   continue   mes   push   

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

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

#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;
}

反向拓扑排序

标签:size   php   ace   can   编号   mem   continue   mes   push   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!