拓扑排序是基于DAG(有向无环图)来排出一个大小顺序,简单来说就是有严格大小关系的绝对不能错,没有严格大小关系的就是顺序随意(但是也要有固定的顺序),将一个图排成有序的一个线性序列。
应用:比如一个很多的2v2比赛(选手有重复),知道其中很多场的结果,然后排出一个总名次;选课,有些课在选之前有先导课,必须学完基础课才能学高级的课。
拓扑排序的实现就是,法①:维护一个入度为0的数组,法②:dfs一个初度为0的数组
#include<iostream>
using namespace std;
#include<stack>
#include<algorithm>
#include<string.h>
typedef struct ArcNode
{
int adjvex;
ArcNode *nextarc;
};
typedef struct
{
int data;
ArcNode *firstarc;
}VNode;
typedef struct
{
VNode AdjList[100];
int vnum,anum;
}ALGraph;
bool CreateGraph(ALGraph &G)
{
scanf("%d%d",&G.vnum,&G.anum);
int i;
for(i=0;i<G.vnum;i++)
{
G.AdjList[i].data=i;
G.AdjList[i].firstarc=new ArcNode;
G.AdjList[i].firstarc=NULL;
}
for(i=0;i<G.anum;i++)
{
int v1,v2;
scanf("%d%d",&v1,&v2);
ArcNode *p1;
p1=new ArcNode;
p1->adjvex=v2;
p1->nextarc=G.AdjList[v1].firstarc;
G.AdjList[v1].firstarc=p1;
}
}
void Find(ALGraph G,int indegree[])
{
//memset(indegree,0,sizeof(indegree));
int i;
for(i=0;i<G.vnum;i++)
indegree[i]=0;
for(i=0;i<G.vnum;i++)
{
ArcNode *p;
p=new ArcNode;
p=G.AdjList[i].firstarc;
while(p!=NULL)
{
indegree[p->adjvex]++;
p=p->nextarc;
}
}
}
bool Topo(ALGraph G,int topo[],int indegree[50])
{
stack<int>s;
while(!s.empty())
s.pop();
int i;
for(i=0;i<G.vnum;i++)
if(!indegree[i])
s.push(i);
int m=0;
while(!s.empty())
{
int temp=s.top();
s.pop();
topo[m]=temp;
m++;
ArcNode *p;
p=new ArcNode;
p=G.AdjList[temp].firstarc;
while(p!=NULL)
{
indegree[p->adjvex]--;
if(!indegree[p->adjvex])
s.push(p->adjvex);
p=p->nextarc;
}
}
//cout<<m<<endl;
for(i=0;i<m;i++)
cout<<topo[i]<<" ";
cout<<endl;
if(m<G.vnum)
return false;
else
return true;
}
int main()
{
ALGraph G;
CreateGraph(G);
int indegree[50];//存储每个点的入度,当入度为0的时候,就可以输出了。
Find(G,indegree);
int i;
int topo[50];//拓扑排序的顺序
Topo(G,topo,indegree);
return 0;
}