反向拓扑排序

老子叫甜甜 提交于 2019-12-09 20:44:49

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

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

#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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!