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