hihoCoder #1174 : 拓撲排序·一 (判斷循環圖)

 

G++ 261ms 13MB

 

 

題意:c++

  給出n門課程的修讀所須要的前置課程的關係,按理說應該是個拓撲圖,可是由於某些緣由致使了混亂,因此有可能不是一個拓撲圖。如今的問題是,判斷該圖是否爲一個拓撲圖(即無環圖)。ide

 

思路:spa

  每次刪除所有入度爲0的結點,一直刪下去確定是沒有任何點存在的,若是不是拓撲圖的話就必有環,那麼確定有點的入度永遠不爲0。若到刪到最後沒有點存在,那麼就是correct的。code

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100100;
 4 
 5 vector< vector<int> >   vect;
 6 int cnt[N]; //記錄每一個點的入度
 7 
 8 bool cal(int n)
 9 {
10     vector<int> a;//存放入度爲0的點
11     for(int i=1; i<=n; i++)    //先在cnt中找到入度爲0的全部點
12         if(!cnt[i])    a.push_back(i);
13     vector<int> b;//臨時存放入度爲0的點
14     while(!a.empty())
15     {
16         b.clear();
17         for(int i=0; i<a.size(); i++)   //每一個入度爲0的點x
18         {
19             for(int j=0; j<vect[a[i]].size(); j++)  //每一個與x相連的點
20             {
21                 cnt[vect[a[i]][j]]--;
22                 if(!cnt[vect[a[i]][j]])//只有那些有變化的點纔可能入度爲0。
23                     b.push_back(vect[a[i]][j]);
24             }
25             vect[a[i]].clear();
26         }
27         a.clear();
28         if(!b.empty())    a.insert(a.end(), b.begin(), b.end());
29     }
30     for(int i=1; i<=vect.size(); i++)
31     {
32         if(cnt[i]>0)
33             return false;
34     }
35     return true;
36 }
37 
38 void init(int n)    //初始化用的
39 {
40     memset(cnt,0,sizeof(cnt));
41     vect.clear();
42     vector<int> tmp;
43     for(int i=0; i<=n; i++)
44         vect.push_back(tmp);
45 }
46 int main()
47 {
48     //freopen("e://input.txt","r",stdin);
49     int t, n, m, a, b;
50     cin>>t;
51     while(t--)
52     {
53         scanf("%d%d",&n,&m);
54         init(n);
55         for(int i=0; i<m; i++)
56         {
57             scanf("%d%d",&a,&b);
58             vect[a].push_back(b);
59             cnt[b]++;
60         }
61         if(cal(n))
62             printf("Correct\n");
63         else
64             printf("Wrong\n");
65     }
66     return 0;
67 }
AC代碼
相關文章
相關標籤/搜索