拓扑排序:
拓扑排序是对有向无环图的一种排序。
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 < u,v > ∈ E(G),则u在线性序列中出现在v之前。
通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。
由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。
循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。
实现
邻接矩阵:v*v
bool G[N][N]; //邻接矩阵存图
int in[N]; //各个顶点的入度 计数
void toposort(int n) //拓扑排序
{
int k=0;
for(int i=1; i<=n; i++) //共进行|G.V|次操作
{
for(int j=1; j<=n; j++) //遍历所有的顶点 找入度为0的
{
if(in[j]==0) //找到
{
printf("%d%c",j,i==n?'\n':' ');
in[j]--; //去掉这个点 让in[j] = -1;
k=j; //记录这个点
break; //跳出循环
}
}
for(int j=1; j<=n; j++) //遍历所有的点
if(G[k][j]==1) //找被此点打败过的点
{
G[k][j]=0; //标记为找到过
in[j]--; //让这个点的入度-1
}
}
}
前向星:v+e
struct node //前向星的结构体
{
int v; //输队编号
int next;
}edge[N*4]; //结构体数组
int head[N]; //头指针数组
int cnt; //下标
int in[N]; //入度数组
void toposort(int n)
{
priority_queue<int,vector<int>,greater<int> >que; //优先队列
for(int i=1; i<=n; i++) //找所有点
if(in[i]==0) //入度为 0
{
que.push(i); //加入队列
in[i]--; //入度 变为 -1
}
int k=1;
while(!que.empty()) //队列不为空
{
int u=que.top(); //取出队首的数
que.pop(); //删除
printf("%d%c",u,k++==n?'\n':' ');
for(int i=head[u]; i!=-1; i=edge[i].next) //与该点相连的
{
node e=edge[i]; //便于书写
in[e.v]--; //点的入度 -1
if(in[e.v]==0) //若此点的 入度为 0
que.push(e.v); //放入队列
}
}
}
STL: v+e
vector<int>G[N]; //vector模拟邻接表
int n,in[N]; //in[]保存每个顶点的入度
void toposort()
{
priority_queue <int,vector <int>,greater<int> > Q; //优先队列队列元素从小到大
for(int i=1; i<=n; i++)
if(in[i] == 0) //入度为0的都压入队列
Q.push(i);
int flag=0;
while(!Q.empty()) //BFS思想
{
int v=Q.top(); //取队顶的那个点遍历
Q.pop(); //删掉该点
if(!flag)
cout<<v;
else
cout<<" "<<v;
flag=1;
for(int i=0; i<G[v].size(); i++) //遍历与该点相邻的点
{
in[G[v][i]]--; //与它相连的点的入度都要减1
if(!in[G[v][i]]) //入度为0压入队列
Q.push(G[v][i]);
}
}
puts("");
}
}
以上代码不是自己敲的