您的位置:首页 > 理论基础 > 数据结构算法

数据结构-有向无环图的拓扑排序(拓扑排序的简单应用)

2022-04-29 19:11 2211 查看

题目链接:https://www.dotcpp.com/oj/problem1707.html

常规问题常规做法,用bfs拓扑思想即可。

但这个题有一个坑点是用队列反而不行了,要用到dfs拓扑思想的队列。

也就是说这个题是dfs+bfs双拓扑思想。

当然,我发现大多数算法思想是依据bfs拓扑思想的,所以说算法实现起来不算太难。

今晚我会根据情况总结一下拓扑排序的简单算法,当然,

拓扑排序的重要应用---关键路径算法我还没完全掌握,所以会根据情况做一下拓扑排序的小结;

回到本题,这个题还要一个小技巧,

就是存图的时候依然是用邻接表存的,虽然题目貌似是要求用邻接矩阵存图。

但是用邻接表存图也是可以的,只要在循环中定义一个临时变量,每次输入这个临时变量并且判断,

如果满足条件就按照拓扑排序的算法进行入度操作;

然后进行常规的拓扑排序算法实现就可以了。

Talk is cheap. Show me the code.

队列代码(仅供参考,当然正规是这样写的,这个题有坑点不会过)

#include<bits/stdc++.h>
using namespace std;
const int num=30010;
queue<int>q;
int n;
vector<int>edge[num];
vector<int>topo;
int in[num];
int main()
{
std::ios::sync_with_stdio(false);
cin>>n;
for(register int i=0;i<n;i++)
{
for(register int j=0;j<n;j++)
{
int temp;
cin>>temp;
if(temp)
{
edge[i].push_back(j);
in[j]++;
}
}
}
for(register int i=0;i<n;i++)
{
if(!in[i])
q.push(i);
}
while(!q.empty())
{
//int x=q.top();
int x=q.front();
q.pop();
topo.push_back(x);
for(register int j=0;j<edge[x].size();j++)
{
int y=edge[x][j];
in[y]--;
if(!in[y])
q.push(y);
}
}
for(register int i=0;i<topo.size();i++)
cout<<topo[i]<<" ";
return 0;
}

AC代码

#include<bits/stdc++.h>
using namespace std;
const int num=30010;
stack<int>q;//坑点是栈
int n;
vector<int>edge[num];//邻接表
vector<int>topo;//拓扑序列
int in[num];//入度数组
int main()
{
std::ios::sync_with_stdio(false);
cin>>n;
for(register int i=0;i<n;i++)
{
for(register int j=0;j<n;j++)
{
int temp;
cin>>temp;//写入临时变量
if(temp)//非0
{
edge[i].push_back(j);//存图
in[j]++;//入度
}
}
}
for(register int i=0;i<n;i++)
{
if(!in[i])
q.push(i);//将度为0的节点入队(栈)
}
while(!q.empty())
{
int x=q.top();//队(栈)首元素
q.pop();
topo.push_back(x);//读入拓扑序列
for(register int j=0;j<edge[x].size();j++)//检查邻居
{
int y=edge[x][j];
in[y]--;///邻居的度减一
if(!in[y])//度为0入队(栈)
q.push(y);
}
}
for(register int i=0;i<topo.size();i++)
cout<<topo[i]<<" ";
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: