1.介绍有向无环图
直接上图
其实这就像生活中买菜做饭一样,要炒菜之前必须买菜和洗菜,如图就是要完成3先完成1和2
借助上面的图和上面的例子介绍一下入度和出度
入度:指向改点的箭头个数
出度:该点指向其他点的箭头个数
2.AOV网:顶点活动图
其实AOV网就是有向无环图的一个实际应用,即将每个点赋予实际意义,并用箭头表示活动的先后顺序
类似下图
3.拓扑排序
概念:拓扑排序是建立在有向图的基础上的一种排序算法。有向图是由节点和有向边组成的图结构,其中有向边指明了节点之间的方向关系。拓扑排序的目标是找到一种节点的线性排列,使得图中的每条有向边的终点在排序中都出现在起点之后。
其实简单的理解就是找到做事情的先后顺序,这个顺序不唯一
应用拓扑排序来对上图排序
先进行买菜,因为买菜的入度为0,买菜以后洗菜的入度减减变成0,故买菜后洗菜,以此类推得到
买菜->洗菜->炒菜->摆盘->吃饭
编程实现拓扑排序的逻辑
找出图中入度为零的点并输出
删除与该点相连接的边
重复上面的操作直到图中没有点了或者图中没有入度为0的点
4.实现拓扑排序
这里用例题来讲解,题目来自牛客网
unordered_map<int,vector<int>> torder;
vector<int> in;
通过torder来建图,in来记录每个点的入度
1.初始化图
for(int i = 0;i<m;i++)
{
int tmp1,tmp2;
cin>>tmp1>>tmp2;
torder[tmp1].push_back(tmp2);
in[tmp2]++;
}
2.实现拓扑
找出图中入度为零的点并输出
删除与该点相连接的边
重复上面的操作直到图中没有点了或者图中没有入度为0的点
queue<int> q;
for(auto [a,b] : torder)
{
if(in[a] == 0) q.push(a);
}
vector<int> ret;
while(!q.empty())
{
int tmp = q.front();q.pop();
ret.push_back(tmp);
for(auto ch : torder[tmp])
{
in[ch]--;
if(in[ch] == 0) q.push(ch);
}
}
3.根据题意输出
bool tm = true;
for(auto ch:in)
{
if(ch != 0)
{
cout<<"-1"<<endl;
tm = false;
break;
}
}
if(tm)
{
for(int i = 0;i<ret.size();i++)
{
if(i<=ret.size()-2)
cout<<ret[i]<<' ';
else cout<<ret[i];
}
}
感谢读者大大读到这里,给个关注,后续持续更新算法内容