概念:
设A有最高优先级,BC优先级相等,D是最低优先级,表示为A->(B,C)->D,ABCD或ACBD这一序列就是就是拓扑序列。
在一个有向图中找一个拓扑序列的过程称为拓扑排序。
这个图必须是有向无环图(DAG)(DAG 就是一个从任何节点出发,只要按照指针方向走,无论选择哪种路径都不能回到起点的图)
基本思想:
1)从有向图中选一个无前驱(入度为0)的顶点 输出;
2)将此顶点和以它为起点的弧删除;
3)重复前两步,直到不存在无前驱的顶点;
4)若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序为一个拓扑序列;
算法步骤:
1、求所有顶点的入度,和它下一节点的出度,可以设两个数组;
2、把所有入度为0的顶点入队列或栈(注意是所有);
3、当栈或队列不为空
- 出栈或队列顶点为u,输出顶点u,然后开始处理它的下一级邻居;
- 顶点u的所有邻接点入度减一,如果有入度为0的顶点,则入栈或队列;
4、最后停止的时候,可以根据出度为0的(既最后一个点)进行其他操作
例如,总路径的条数种类
5、若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序为一个拓扑序列;
其实用拓扑排序的很大一个原因就是 它原本就是有向无环图
注意队列的先进先出,所以等级高的一定先被处理了
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <queue>
#include <list>
using namespace std;
typedef long long ull;
const int N=1000001;
int ans;
ull n,k,x,y,m,sum=0;
int a,b;
int in[N],out[N];
queue<int>q;
vector<int>e[500005];//可理解为二维
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
e[i].clear();//初始化
}
for(int i=1;i<=m;i++)
{
cin>>a>>b;
e[a].push_back(b);//把相应值存储到结点a邻接表中
out[a]++;//上级的出
in[b]++;//下级的入
}
for(int i=1;i<=n;i++)//找寻最开头的点
{
if(in[i]==0)
{
num[i] =1;
q.push(i);
}
}
while(!q.empty())
{
int head = q.front();//队首
q.pop();
int len = e[head].size();//邻居有多少
for(int i=0;i<len;i++) //把他的所有邻居都处理了
{
int x = e[head][i];//当前点
in[x]--;//入度
if(in[x]==0) q.push(e[head][i]);
}
}
for(int i=1;i<=n;i++)//找到最末端的点
{
if(out[i]==0) //相关操作
}
return 0;
}