拓扑排序例题

本文深入探讨拓扑排序,通过例题讲解拓扑排序的应用,包括Legal or Not、Skiing、优先队列+拓扑等场景。强调在某些情况下,虽然拓扑排序不一定保证最小元素在前,但最大元素总是在较小元素之后。通过建立反图并进行反向拓扑排序,可以找到满足条件的正确顺序。
摘要由CSDN通过智能技术生成

不懂的看这里

拓扑排序

以下是例题:

拓扑排序·一

简单拓扑判环

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
vector<int> G[maxn];
int inDeg[maxn];
int n,m;
queue<int>q;
int sum;
bool top(){
   
while(!q.empty()) q.pop();
sum = 0;


for(int  i = 1;i <= n ; i++) if(!inDeg[i]) q.push(i);
while(!q.empty()){
   
    int to = q.front();
    q.pop();
    sum ++;
    for(int  i = 0; i < G[to].size(); i++){
   
        int edge = G[to][i];
        inDeg[edge] --;
        if(!inDeg[edge]) q.push(edge);
    }

}
if(sum == n) return 1;
else return 0;
}


int main(){
   
   // int n ;
   int t;
    cin >> t ;
    while(t--){
   
    cin >> n;
    cin >> m;
    memset(G,0,sizeof(G));
    memset(inDeg,0,sizeof(inDeg));
    for(int i  =1;i <= m ; i++) {
   
        int u , v;
        cin >> u >> v;
        G[u].push_back(v);
        inDeg[v]++;
    }
    if(top()) cout << "Correct" << endl;
    else cout << "Wrong" << endl;
    }
    return 0;

}

Legal or Not

同上,注意0 ~ n-1

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
const int mod = 142857;
vector<int> G[maxn];
int virus[maxn];
int inDeg[maxn];
int n,m;
int sum = 0;
queue<int>q;

bool topsort(){
   
    while(!q.empty()) q.pop();
    sum = 0;


    for(int  i = 0;i < n ; i++) if(!inDeg[i]) q.push(i);
        while(!q.empty()){
   
            int to = q.front();
            q.pop();
            sum ++;
            for(int  i = 0; i < G[to].size(); i++){
   
                int edge = G[to][i];
                inDeg[edge] --;
                if(!inDeg[edge]) q.push(edge);
      //  virus[edge] = (virus[edge] + virus[to]) % mod;
            }

        }
        if(sum == n)return 1;
        else return 0;
    }


    int main(){
   
   // int n ;

        int k ;

        while(cin >> n){
   
            cin >> m;
            if(!n&&!m) break;
   // cin >> k;
    //memset(virus, 0 , sizeof virus);
    //int x;
    //for(int i = 1; i <= k ; i++) cin >> x,virus[x] ++;
            memset(G,0,sizeof(G));
            memset(inDeg,0,sizeof(inDeg));
            for(int i  =
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值