PAT_甲級_1146 Topological Order

題目大意:

給定一個有向圖,N個頂點,M條邊,現給定K個查詢,每個查詢輸入一個序列,判斷該序列是不是該圖的拓撲排序序列,若是不是,輸出該序列的編號(從0開始)算法

算法思路:

模擬拓撲排序的過程,對於輸入的序列,先檢查其入度是否爲0,不爲0說明該序列不是拓撲排序序列,不然就將該結點的鄰接點的入度所有減一,依次向下進行判斷,知道退出循環。爲了防止最後一個測試點的格式錯誤,全部不是拓撲排序的序列編號都使用result數組保存,最後輸出結果便可。數組

提交結果:

image.png

AC代碼:

#include<cstdio>
#include<vector>

using namespace std;

const int maxn = 1005; 
int inDegree[maxn];// 每個結點的入度 
int tempInDegree[maxn];// 每次查詢暫存入度數組 
int query[maxn];// 每次查詢的序列 
vector<int> Adj[maxn];// 鄰接表,保存每個結點的全部鄰接點 
vector<int> result;// 保存全部不是拓撲排序序列的編號 
int N,M;

bool isTopologicalOrder(){
    for(int i=1;i<=N;++i){
        // 從新賦值入度數組 
        tempInDegree[i] = inDegree[i];
    }
    for(int i=0;i<N;++i){
        if(tempInDegree[query[i]]!=0){
            return false;
        }
        for(auto &item:Adj[query[i]]){
            // 將當前頂點的鄰接點的入度減一
            --tempInDegree[item];
        }
    }
    return true;
}

int main(){
    scanf("%d %d",&N,&M);
    for(int i=0;i<M;++i){
        int a,b;
        scanf("%d %d",&a,&b);
        ++inDegree[b];
        Adj[a].push_back(b);
    }
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;++i){
        for(int j=0;j<N;++j){
            scanf("%d",&query[j]);
        }
        if(!isTopologicalOrder()){
            result.push_back(i);
        }
    }
    for(int i=0;i<result.size();++i){
        printf("%d",result[i]);
        if(i<result.size()-1) printf(" ");
    }
    return 0;
}
相關文章
相關標籤/搜索