題解報告:hihoCoder #1174:拓撲排序·一
題目鏈接:https://hihocoder.com/problemset/problem/1174
時間限制:10000ms 單點時限:1000ms 內存限制:256MB描述
由於今天上課的老師講的特別無聊,小Hi和小Ho偷偷地聊了起來。
小Ho:小Hi,你這學期有選什麽課麽?
小Hi:挺多的,比如XXX1,XXX2還有XXX3。本來想選YYY2的,但是好像沒有先選過YYY1,不能選YYY2。
小Ho:先修課程真是個麻煩的東西呢。
小Hi:沒錯呢。好多課程都有先修課程,每次選課之前都得先查查有沒有先修。教務公布的先修課程記錄都是好多年前的,不但有重復的信息,好像很多都不正確了。
小Ho:課程太多了,教務也沒法整理吧。他們也沒法一個一個確認有沒有寫錯。
小Hi:這不正是輪到小Ho你出馬的時候了麽!
小Ho:哎??
我們都知道大學的課程是可以自己選擇的,每一個學期可以自由選擇打算學習的課程。唯一限制我們選課是一些課程之間的順序關系:有的難度很大的課程可能會有一些前置課程的要求。比如課程A是課程B的前置課程,則要求先學習完A課程,才可以選擇B課程。大學的教務收集了所有課程的順序關系,但由於系統故障,可能有一些信息出現了錯誤。現在小Ho把信息都告訴你,請你幫小Ho判斷一下這些信息是否有誤。錯誤的信息主要是指出現了"課程A是課程B的前置課程,同時課程B也是課程A的前置課程"這樣的情況。當然"課程A是課程B的前置課程,課程B是課程C的前置課程,課程C是課程A的前置課程"這類也是錯誤的。
輸入
第1行:1個整數T,表示數據的組數T(1 <= T <= 5)
接下來T組數據按照以下格式:
第1行:2個整數,N,M。N表示課程總數量,課程編號為1..N。M表示順序關系的數量。1 <= N <= 100,000. 1 <= M <= 500,000
第2..M+1行:每行2個整數,A,B。表示課程A是課程B的前置課程。
輸出
第1..T行:每行1個字符串,若該組信息無誤,輸出"Correct",若該組信息有誤,輸出"Wrong"。
- 樣例輸入
2 2 2 1 2 2 1 3 2 1 2 1 3
- 樣例輸出
Wrong Correct
解題思路:拓撲排序裸題。判斷一下出隊元素的個數是否為n,如果是,則為正確,否則必定出現回路,為錯誤。
AC代碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=100005; 4 vector<int> vec[maxn];//鄰接表,每個節點保存與它相連的邊的另一個端點 5 queue<int> que; 6 int t,n,m,u,v,InDeg[maxn];//記錄每個節點的入度,num用來表示節點的個數 7 bool topsort(){ 8 int num=0; 9 for(int i=1;i<=n;++i) 10 if(!InDeg[i])que.push(i);//預處理,先將入度為0的節點編號入隊 11 while(!que.empty()){ 12 int now=que.front();que.pop();num++; 13 for(unsigned int i=0;i<vec[now].size();++i) 14 if(--InDeg[vec[now][i]]==0)que.push(vec[now][i]); 15 } 16 if(num==n)return true;//如果出隊個數小於n,說明不是有向無環圖 17 else return false; 18 } 19 int main() 20 { 21 cin>>t; 22 while(t--){ 23 cin>>n>>m; 24 for(int i=1;i<=n;++i)vec[i].clear();//全部清空 25 memset(InDeg,0,sizeof(InDeg));//全部頂點的度清0 26 while(m--){ 27 cin>>u>>v; 28 vec[u].push_back(v);//u指向v 29 InDeg[v]++;//v的入度加1 30 } 31 if(topsort())cout<<"Correct"<<endl; 32 else cout<<"Wrong"<<endl; 33 } 34 return 0; 35 }
題解報告:hihoCoder #1174:拓撲排序·一