拓扑排序是DAG(无圈有向图)引出的新概念,它是对DAG图的顶点的一种排序。
如果图中存在两点 vi --> vj,拓扑排序保证排序结果,vj出现在vi后面。我们可以用这个特性来解决优先级问题。
而且,如果这个图有圈,我们的拓扑排序将会失败。当然拓扑排序结果也并不唯一。
对于拓扑排序,我们先对每一个顶点计算入度,然后将入度为0的顶点放入队列。当队列不空,删除队首顶点,并把与队首顶点邻接的顶点入度-1,在把入度为0的放入队列。此时拓扑排序就是出队顺序。
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int MAX_N=10; //暂且假定图的 大小
struct GraphVertex{ //邻接表
vector <int> vertices;
}G[MAX_N];
int indegree[MAX_N]; //入度数组,储存,每一个顶点的入度
int TopNum[MAX_N]; //拓扑编号数组储存每一个顶点的排序编号
void TopSort(int n)
{
queue <int> q; //设置队列
int v,counter=0;
for (int i=1;i<=n;i++)
{
if (indegree[i]==0) //入度为 0,放入队列
q.push(i);
}
vector<int> :: iterator it;
while(!q.empty())
{
v=q.front();
q.pop();
printf ("%d ",v);
TopNum[v]=++counter;//分配入度编号
for (it=G[v].vertices.begin();it!=G[v].vertices.end();it++)
{
indegree[*it]--; //对v邻接的每一个顶点入度-1
if (indegree[*it]==0) //入度为 0,放入队列
q.push(*it);
}
}
printf ("\n");
if (counter!=n) //只要无法对所有顶点拓扑排序,说明这个不是无圈有向图。
{
printf ("这是个有环图\n");
}
}
int main()
{
int n,u,v,m;
scanf ("%d %d",&n,&m);
for (int i=0;i<m;i++)
{
scanf ("%d %d",&u,&v);
G[u].vertices.push_back(v);
indegree[v]++;
}
TopSort(n);
return 0;
}
来几道例题