对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。
1.每个顶点出现且只出现一次。
2.若存在一条从顶点 A 到顶点 B ,则A为B的前序 。
but,该如何实现它?
首先,我用了模拟法
#include <bits/stdc++.h>
using namespace std;
const int maxn=100+5,maxm=1000+5;
int a[maxn][maxn],rd[maxn],n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
a[x][y]=1;//将x与y建立一座桥
rd[y]++;//它的入度加一
}
for(int i=1;i<=n;i++){
int k;
for(int j=1;j<=n;j++)
if(rd[j]==0){//如果没有点指它
k=j;//存下
break;//退出
}
cout<<k<<" ";//输出当前找到的
for(int j=1;j<=n;j++)
if(a[k][j])//如果它与k之间有桥
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);//存入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];
rd[u]--;//它的入度减一
if(rd[u]==0)//将u给压入掉
q.push(u);
}
}
return 0;
}