拓扑排序

#include <bits/stdc++.h>
using namespace std;
#define MAX 200
#define DIAN 100
#define INF 0x7fffffff
int u[MAX+1],v[MAX+1],w[MAX+1],first[MAX+1],next[MAX+1],graph[DIAN+1][DIAN+1];
int numdian,numbian;
int rudu[DIAN+1];
void tuo(){
    queue<int> q;
    for(int i=1;i<=numdian;i++)
        if(rudu[i]==0) q.push(i);
    while(!q.empty()){
        int p=q.front();
        q.pop();
        cout<<p<<" ";
        int k=first[p];
        while(k!=-1){
            rudu[v[k]]--;
            if(rudu[v[k]]==0) q.push(v[k]); 
            k=next[k];
        }
    }
    cout<<endl;
}
//使用dfs来进行拓扑排序
//1 假设从一个点开始可以dfs到所有的点,那么这个点一定入度为0(在无环情况下),那么点v即放置正确
//递归的看,对于遍历到的点,去除他到达不了的点,又变回了情况1
int visit[DIAN+1],out[DIAN+1],index;
//0 未访问,1访问过,-1正在访问
//返回值代表有没有环
bool f(int x){
    visit[x]=-1;
    for(int i=1;i<=numdian;i++){
        if(graph[x][i]!=0){
            if(visit[i]==-1) return false;
            if(visit[i]==0){
                if(!f(i)) return false;
            }
        }
    }
    visit[x]=1;
    out[index]=x;
    index--;
    return true;
}

bool topo(){
    index=numdian;
    memset(visit,0,sizeof(visit));
    for(int i=1;i<=numdian;i++){
        if(!visit[i]){
            if(!f(i)) return false;
        }
    }
    return true;
}

int main()
{   
    cin >> numdian >> numbian;
    memset(rudu,0,sizeof(rudu));
    memset(graph,0,sizeof(graph));
    for(int i=1;i<=numbian;i++) first[i]=-1;
    for(int i=1;i<=numbian;i++){
        cin>>u[i]>>v[i]>>w[i];
        graph[u[i]][v[i]]=w[i];
        rudu[v[i]]++;
        next[i]=first[u[i]];
        first[u[i]]=i;
    }
    tuo();
    if(topo()){
        for(int i=1;i<=numdian;i++) cout<<out[i]<<" ";
        cout<<endl;
    }
    return 0;
}

 

posted @ 2020-06-06 21:49  西伯利亚挖土豆  阅读(138)  评论(0编辑  收藏  举报