什么是拓扑排序?
实现过程:
解决的办法其实很简单
Ò1、在有向图中选一个没有前驱的顶点且输出之。
Ò2、从图中删除所有以它为尾的弧。
Ò
Ò3、重复上述两步,直到全部顶点已经输出,或者是当前图中不存在无前驱的顶点为止。后一种情况则说明图中有环存在。
方法:
拓扑排序的方法和步骤: (1)在图中选一个没有前趋的顶点并输出之 (2)删除该顶点及由它发出的各边,直到图中不存在没有前趋的顶点为止。 若图中存在回路,拓扑排序无法进行。 以下是将一AOV网进行拓扑排序的算法: 网采用邻接矩阵A表示,若a[i,j]=1,表示活动i先于j,a[i,j]=0,表示活动i与j不存在先后关系。 (1)计算各顶点的入度 (2)找入度为零的点输出之,删除该点,且与该点关联各点的入度减1 (3)若所有顶点都输出完毕。
模板代码
邻接表代码#include<cstdio> #include<cstdlib> #include<cstring> using namespace std; int map[510][510];//前驱数量 int indegree[510]; int queue[510];//保存拓扑序列 void topo(int n) { int i,j,m,t=0; for(j=0;j<n;++j){ for(i=1;i<=n;++i){ // if(indegree[i]==0){//找出前驱数量为零的的点即每次找到第一名 m=i;break; } } queue[t++]=m;indegree[m]=-1;//将第一名的前驱数量设为-1 for(i=1;i<=n;++i){//第二步将前驱中含有第一名的点前驱数量减1 if(map[m][i])indegree[i]--; } } printf("%d",queue[0]);//输出拓扑序列 for(i=1;i<n;++i){ printf(" %d",queue[i]); } printf("\n"); } int main() { int n,m,i,j,a,b; while(scanf("%d%d",&n,&m)!=EOF){ memset(indegree,0,sizeof(indegree));//初始化 memset(map,0,sizeof(map)); for(i=0;i<m;++i){ scanf("%d%d",&a,&b); if(map[a][b]==0){ map[a][b]=1;indegree[b]++;//第一步记录关系和点的前驱数量 } } topo(n);//调用拓扑排序 } return 0; }
队列实现码#include<cstdio> #include<cstdlib> #include<cstring> using namespace std; int indegree[51000]; int queue[51000]; struct Node{ int next; int to; }A[51000]; int head[51000]; void topo(int n) { int i,j,top,t=0; for(j=0;j<n;++j){ for(i=1;i<=n;++i){ if(indegree[i]==0){ top=i;break; } } queue[t++]=top;indegree[top]=-1; for(int k=head[top];k!=-1;k=A[k].next){ indegree[A[k].to]--; } } printf("%d",queue[0]); for(i=1;i<n;++i){ printf(" %d",queue[i]); } printf("\n"); } int main() { int n,m,i,j,a,b; while(scanf("%d%d",&n,&m)!=EOF){ memset(indegree,0,sizeof(indegree)); memset(head,-1,sizeof(head)); for(i=0;i<m;++i){ scanf("%d%d",&a,&b); A[i].to=b; A[i].next=head[a]; head[a]=i; indegree[b]++; } topo(n); } return 0; }
<span style="font-size:14px;">#include<cstdio> #include<cstdlib> #include<cstring> #include<queue> #include<functional> using namespace std; int map[510][510]; int indegree[510]; void topo(int n) { priority_queue<int,vector<int>,greater<int> >Q; int i,j,m,t=0; for(i=1;i<=n;++i){ if(indegree[i]==0){ Q.push(i); } } int sign=1; while(!Q.empty()){ int top=Q.top();Q.pop(); indegree[top]=-1; if(sign) printf("%d",top); else printf(" %d",top); sign=0; for(i=1;i<=n;++i){ if(map[top][i]){ indegree[i]--; if(indegree[i]==0){ Q.push(i); } } } } printf("\n"); } int main() { int n,m,i,j,a,b; while(scanf("%d%d",&n,&m)!=EOF){ memset(indegree,0,sizeof(indegree)); memset(map,0,sizeof(map)); for(i=0;i<m;++i){ scanf("%d%d",&a,&b); if(map[a][b]==0){ map[a][b]=1;indegree[b]++; } } topo(n); } return 0; } </span>