1. 程式人生 > 實用技巧 >PAT A1146 Topological Order (25分)

PAT A1146 Topological Order (25分)

這是PAT圖論中很少見拓撲排序問題,基本上不考,思路也偏向與驗證排序正確與否,驗證思路為:
在輸入邊的時候,記錄所有頂點的單向鄰接點,並且記錄所有點的入度。查詢時,每輸入一個點,就判斷其入度是否為0,不為0,則不是拓撲排序,然後將此點指向的所有點的入度減一,查詢至結束,輸出即可

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 1010;
const int M = 10010;
const int K = 110;
vector<int>G[N];
int inDegree[N];
bool istopol[K];

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 0 ; i < m ; i++){
        int v,u;
        scanf("%d%d",&v,&u);
        G[v].push_back(u);//從v到u
        inDegree[u]++;//u的入度+1
    }
    
    int k;
    scanf("%d",&k);
    fill(istopol,istopol+k,true);//先設定為全對
    
    int tempinDegree[n+1];//0不用
    int order[n];
    
    for(int i = 0;i<k;i++){//k次驗證
        for(int j = 1;j<=n;j++){
            tempinDegree[j] = inDegree[j];//複製入度
        }
        for(int j = 0;j < n;j++){
            scanf("%d",order+j);
        }
        for(int j = 0;j< n;j++){
            int v = order[j];
            if(tempinDegree[v]!=0){
                istopol[i] =false;
                break;
            }else{
                for(int gt = 0;gt<G[v].size();gt++){
                    tempinDegree[G[v][gt]]--;//所有連線點入度-1
                }
            }  
        }
    }
    
    
    //print
    bool flag = true;
    for(int i = 0;i<k;i++){
        if(istopol[i]==false){
            if(flag==false) printf(" ");
            printf("%d",i);
            flag = false;
        }
    }
}