BFS
整个图中按照各个路径的优先级先后进行,将同一优先级的路径处理完了之后再进行下一优先级的处理
具体做法
输入路径时初始化每个点的入度大小,现将入度为零的点加入优先对列,然后每一步输出队列首元素,并且把与队首元素相邻的元素入度减一,这样就做到了按照优先级的移动,直到队列里无元素,这样所有输出的元素就是一个拓扑序列。
代码一:用二维数组代替队列直接操作 较好理解
#include<iostream>
#include<algorithm>
using namespace std;
int g[maxn][maxn];
int inrt[maxn];
void solve(){
for(i=1;i<=n;i++)
for(j=1;i<=i;j++)
{
if(inrt[j]==0)
inrt=-1;
if(i==n) cout<<j<<endl;
else cout<<j<<" ";
for(k=1;k<=j;k++){
if(g[j][k]) inrt[k]--;
}
}
}
int main(){
int n,x,y;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>x>>y;
g[x][y]=1;
g[y][x]=1;
inrt[y]++;
}
solve();
return 0;
}
二:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 10000;
struct Node{
int indegree;
int num;
int id;
}N[maxn];
int V,E;
int d[maxn][maxn];
void Init()
{
memset(d,0,sizeof(d));
for(int i=0; i<V; i++)
{
N[i].indegree = 0;
N[i].num = 0;
N[i].id = i;
}
return;
}
int main()
{
scanf("%d%d",&V,&E);
Init();
int s,t;
for(int i=0; i<E; i++)
{
scanf("%d%d",&s,&t);
d[s][t] = 1;
N[t].indegree++;
}
int counter = 0;
queue<Node> q;
for(int i=0; i<V; i++)
{
if(!N[i].indegree)
{
q.push(N[i]);
}
}
while(!q.empty){
Node v=q.front();
q.pop();
N[v.id]=counter++;
for(i=0;i<V;i++)
{
if(d[v.id][i])
{
N[i].indegree()--;
if(N[i].indegree()]
{
q.push(N[i]);
}
}
}
}
for(int i=0; i<V; i++)
{
if(N[i].num==i)
cout<<N[i].id<<" ";
}
return 0;
}
DFS:
根据dfs的规则,从一条路开始探索直到最深,然后再逐层回退,。这个过程正好可以表现出点之间的优先级关系
在dfs的基础上添加表示每个点的入度的数组,那么就是每次for循环只有没访问过且入度为0的节点更新到答案数组中,每次dfs之后都将标志清空,将入度回复,这样和全排列一样最后可以生成按字典序由小到大的拓扑序列
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int maxn=?;
int n,m;
vector<int> G[maxn];
int ans[maxn],in[maxn];
bool vis[maxn];
void dfs(int x){
if(x==n+1){
for(int i=1;i<=n;i++)
printf("%d%c",ans[i],i==n?'\n':' ');
return;
}
for(int i=1;i<=n;i++){
if(!vis[i]&&!in[i]){
ans[x]=i;
vis[i]=1;
for(int j=0;j<G[i].size();j++) in[G[i][j]]--;
dfs(x+1);
vis[i]=0;
for(int j=0;j<G[i].size();j++)
in[G[i][j]]++;
}
}
}
int main()
{
int a,b;
cin>>n>>m;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
G[i].clear();
while(m--){
scanf("%d%d",&a,&b);
G[a].push_back(b);
in[b]++;
}
dfs(1);
return 0;
}
本文介绍了拓扑排序的两种方法:BFS(广度优先搜索)和DFS(深度优先搜索)。BFS通过优先队列实现,优先处理入度为零的节点。DFS则结合入度数组,确保每次只访问未访问过且入度为0的节点,生成字典序最小的拓扑序列。
582

被折叠的 条评论
为什么被折叠?



