拓扑排序算法
前置知识:
1.DAG图:一个无环的有向图,即有向无环图。
2.AOV网络:在⼀个表示⼯程的有向图中,⽤顶点表示活动,⽤弧表示活动之间的优先关系的有向图称为顶点表示活动的⽹(Activity On Vertex Network),简称AOV⽹。
拓扑排序:其实就是对⼀个DAG图构造拓扑序列的过程。
拓扑排序算法:kahn(卡恩)算法(基于BFS)和 基于DFS的算法。
kahn(卡恩)算法
可以判环
时间复杂度:O(V+E)
有环就没有拓扑序列
C++
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
//有向图------>判环
int n,m;
struct Edge{//只求拓扑序列不用带边权
int to,next;
}e[10005];
int h[105];
int ind[105];//入度
int cnt;
int topo[105],k=0;
void add(int u,int v){
e[cnt].to=v;
e[cnt].next=h[u];
h[u]=cnt;
cnt++;
}
bool kahn(){
queue<int> q;
for(int i=1;i<=n;++i){
if(ind[i]==0){
q.push(i);
}
}
int x,y;
while(!q.empty()){
x=q.front();
q.pop();
topo[++k]=x;//从1开始计数
for(int i=h[x];i!=-1;i=e[i].next) {
y=e[i].to;
ind[y]--;
if(ind[y]==0) q.push(y);
}
}
if(k==n) return true;//无环
else return false;//成环
}
int main(){
cin>>n>>m;
memset(h,-1,sizeof h);
int u,v;
for(int i=1;i<=m;++i){
cin>>u>>v;
add(u,v);
ind[v]++;
}
if(kahn()){
for(int i=1;i<=k;++i){
cout<<topo[i]<<" ";
}
} else{
cout<<"有环\n";
}
return 0;
}
例题
C++
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int n;
struct Edge{
int to,next;
}e[100005];
int h[10005],cnt;
int ind[10005];
int t[10005];//每个点需要的时间
int ed[10005];//每个点的完成时间
void add(int u,int v){
e[cnt].to=v;
e[cnt].next=h[u];
h[u]=cnt;
cnt++;
}
void kahn(){
queue<int> q;
for(int i=1;i<=n;++i){
if(ind[i]==0){
q.push(i);
ed[i]=t[i];//没有前置活动
}
}
int u,v;
while(!q.empty()){
u=q.front();
q.pop();
for(int i=h[u];~i;i=e[i].next){
v=e[i].to;
ind[v]--;
ed[v]=max(ed[v],ed[u]+t[v]); //更新y的结束时间
if(ind[v]==0){
q.push(v);
}
}
}
}
int main(){
cin>>n;
int u,v;
memset(h,-1,sizeof h);
for(int i=1;i<=n;++i){
cin>>u;
cin>>t[u];//注意不要同行读入
while(cin>>v){
if(v==0) break;
add(u,v);
ind[v]++;
}
}
kahn();
int ans=-1;
for(int i=1;i<=n;++i){
ans=max(ans,ed[i]);
}
cout<<ans<<endl;
return 0;
}
P1983 [NOIP 2013 普及组\] 车站分级 - 洛谷](https://www.luogu.com.cn/problem/P1983)
```C++
#include