1. 程式人生 > >題解報告:hihoCoder #1174:拓撲排序·一

題解報告:hihoCoder #1174:拓撲排序·一

TP 格式 eof max bits 前置 ++ 什麽 ==

題目鏈接: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:拓撲排序·一