Kahn算法

适用于有向图

算法核心:用一个队列维护一个入度为0度点的集合。

//点数为n,边数为m,din标记入度为0度点,tp为装拓扑序列的数组,mapp为需要传入的图
bool toposort(int& n,vector<int>& din,vector<int>& tp,vector<vector<int>>& mapp){
    queue<int> q;
    for(int i=1;i<=n;i++){
        if(!din[i])q.push(i);//初始化,压入所有入度为0的点
    }
    while(!q.empty()){
        int x=q.front();
        q.pop();
        tp.push_back(x);
        for(auto y:mapp[x]){
            if(--din[y]==0)q.push(y);//删除入度,同时将入度为0的点排进队列
        }
    }
    return tp.size()==n;
}

int n,m;
cin >> n>>m;
vector<vector<int>> v(n+1);//图用的二维可变数组
vector<int> din(n+1,0),topo;
for(int i=0;i<m;i++){
    int a,b;
    cin>>a>>b;
    v[a].push_back(b);//建图
    din[b]++;//标记点的入度
}
if(!toposort(n,din,topo,v)){
    cout<<"-1\n";
}
else
    for(auto x:topo){cout<<x<<"\n";}

posted on 2024-03-24 16:56  漫卷  阅读(24)  评论(0)    收藏  举报