拓扑排序:大学-高中阶段自由选课
在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:
1.每个顶点出现且只出现一次。
2.若存在一条从顶点 A 到顶点 B ,则A为B的前序 。
Tips:有向无环图才有拓扑排序。
c++学习历程(提高组必备):
语言->基础算法(高精度,枚举,分治等等)->搜索->DP->数据结构(线性,树,图)
最重要的是:
多刷题!!!
复习:
1.入度:有几条边与它相连
2.队列是神马???
队列用于线性表(主要),队列可以理解为一个数组,f为队首,先将f队首指向0,队尾为1
一.邻接矩阵来做
#include <bits/stdc++.h>
using namespace std;
const int maxn=100+5,maxm=1000+5;
int a[maxn][maxn],rd[maxn],n,m;//rd为入度
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
a[x][y]=1;//将a[x][y]设为已读
rd[y]++;//它的入度加一
}
for(int i=1;i<=n;i++){
int k;
for(int j=1;j<=n;j++)
if(rd[j]==0){//如果入度为0
k=j;//已排
break;//退出循环
}
cout<<k<<" ";//输出
for(int j=1;j<=n;j++)
if(a[k][j])//如果它已经排过了
rd[j]--;
rd[k]=-1;//这个点就没用了
}
return 0;
}
二.用vector来做(用于稀疏图)
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn=10000+10;
int n,m,rd[maxn];
vector<int>a[maxn];//vector大法好!!!
queue<int>q;//定义队列
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
a[x].push_back(y);//输入
rd[y]++;//入度加一
}
for(int i=1;i<=n;i++)
if(rd[i]==0)
q.push(i);//记住第一个
while(!q.empty()){//当队列不空
//rd[k]=-1这句话不再需要,如果它不是-1,那不就说明这是一个环了吗?
int k=q.front();//定义k为队首
cout<<k<<endl;//输出
q.pop();//弹出队首
for(int j=0;j<a[k].size();j++){
int u=a[k][j];//定义一个u
rd[u]--;//它的入度减一
if(rd[u]==0)//将u给push掉
q.push(u);
}
}
return 0;
}
一道练习题:https://blog.csdn.net/qq_42875611/article/details/82928520
已写题解。