給定一個有向圖,N個頂點,M條邊,現給定K個查詢,每個查詢輸入一個序列,判斷該序列是不是該圖的拓撲排序序列,若是不是,輸出該序列的編號(從0開始)算法
模擬拓撲排序的過程,對於輸入的序列,先檢查其入度是否爲0,不爲0說明該序列不是拓撲排序序列,不然就將該結點的鄰接點的入度所有減一,依次向下進行判斷,知道退出循環。爲了防止最後一個測試點的格式錯誤,全部不是拓撲排序的序列編號都使用result數組保存,最後輸出結果便可。數組
#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; }