top 排序

求出一个这个工程的工作序列的算法被成为拓扑排序。
比如说 1,5,2,3,6,4 就可以算作一个工作序列。
拓扑排序的过程大概是这样的:
1 选择一个入度为 0 的结点并直接输出。
2 删除这个结点以及与它关联的所有边。
3 重复步骤 (1) 和 (2),直到找不到入度为 0 的结点。
通常情况下,在实现的时候会维护一个队列以及每个结点的入度。在删
除边的时候顺便把相应结点的入度减去,当这个结点入度为 0 的时候直接
将其加入队列

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=10000;
int ans[maxn];
int vis[maxn];
int in[maxn];
int top;

struct my{
 int v;
 int next;
};

my bian[maxn];
int adj[maxn];
int fa;

void myinsert(int u,int v){
     bian[++fa].v=v;
     bian[fa].next=adj[u];
     adj[u]=fa;
}

void bfs(int x){
  queue<int>q;
  q.push(x);
  vis[x]=true;
  while(!q.empty()){
    int u=q.front();
    q.pop();
    ans[++top]=u;
    for (int i=adj[u];i!=-1;i=bian[i].next){
        in[bian[i].v]--;
        if(!vis[bian[i].v]&&in[bian[i].v]==0){
            q.push(bian[i].v);
            vis[bian[i].v]=true;
        }
    }
  }
}

int main(){
    memset(bian,-1,sizeof(bian));
    memset(adj,-1,sizeof(adj));
    int m,n;
    scanf("%d%d",&n,&m);
    int u,v,zhi;
    for (int i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        myinsert(u,v);
    }
    for (int i=1;i<=n;i++){
        for (int j=adj[i];j!=-1;j=bian[j].next){
            in[bian[j].v]++;
        }
    }
    for (int i=1;i<=n;i++){
        if(in[i]==0&&!vis[i]) bfs(i);
    }
    for (int i=1;i<=top;i++) printf("%d ",ans[i]);
return 0;
}

posted @ 2018-01-22 19:30  lmjer  阅读(890)  评论(0编辑  收藏  举报