拓扑排序的裸体,全裸的那种一点变形和要求都没有
用DFS来实现
//用dfs解决拓扑排序 //用一个标记数组vis来标记 //0表示还没有访问过,1表示正在访问,2表示已经访问过并且存入拓扑数组 #include <stdio.h> #include <string.h> #define MAX 110 int g[MAX][MAX],vis[MAX]; int n,m,c,top[MAX]; int dfs(int u) { int v; vis[u]=1; for(v=1; v<=n; v++) if(g[u][v]) { if(vis[v]==1) return 0; //说明有环不存在拓扑序列 else if(vis[v]==0 && !dfs(v)) return 0; } vis[u]=2; top[--c]=u; return 1; } int toposort() { int u; for(c=n,u=1; u<=n; u++) if(!vis[u]) dfs(u); return 1; } int main() { int i,u,v,ok; while(scanf("%d%d",&n,&m)!=EOF) { if(!n && !m) break; memset(vis,0,sizeof(vis)); memset(g,0,sizeof(g)); memset(top,0,sizeof(top)); for(i=1; i<=m; i++) { scanf("%d%d",&u,&v); g[u][v]=1; } toposort(); for(i=0; i<n; i++) if(!i) printf("%d",top[i]); else printf(" %d",top[i]); printf("\n"); } return 0; }
下面的代码可以当做模板来用了…………,完全用STL的vector和queue来实现的
算法就是一开始先扫描n个点,把找到入度为0的顶点入队,然后队头元素出队,删除所有以该顶点为弧尾的弧,对应的弧头的入度减1,减1后如果入度为0,那么就入队。以此类推,直到整个队列为空就输出了整个拓扑序列(这里是默认这个图是dag,一定能构建出一个拓扑序列)
#include <stdio.h> #include <string.h> #include <vector> #include <queue> using namespace std; #define N 110 #define M 10100 vector<int> g[N]; queue<int> q; int in[N]; int n,m; int main() { int i,j,u,v,len,flag; while(1) { scanf("%d%d",&n,&m); if(!n && !m) break; for(i=1; i<=n; i++) { in[i]=0; g[i].clear(); } for(i=0; i<m; i++) { scanf("%d%d",&u,&v); g[u].push_back(v); in[v]++; } flag=0; for(i=1; i<=n; i++) if(!in[i]) q.push(i); while(!q.empty()) { i=q.front(); if(!flag) printf("%d",i) , flag=1; else printf(" %d",i); q.pop(); len=g[i].size(); for(j=0; j<len; j++) { if( !(--in[g[i][j]]) ) q.push(g[i][j]); } } printf("\n"); } return 0; }