pat 任務調度的合理性 ——拓撲排序

  拓撲排序概念:在一個有向圖中,對所有的節點進行排序,要求沒有一個節點指向它前面的節點。
  過程:先統計所有節點的入度,對於入度爲0的節點就可以分離出來,然後把這個節點指向的節點的入度-1。重複此過程直至所有節點都被分離出來。 PS:如果最後不存在入度爲0的節點,那就說明有環,不存在拓撲排序,也就是很多題目的無解的情況 。
  搞懂拓撲排序後,這個題目就是個模板題,代碼如下:

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int maxn=105;
queue<int> q;
vector<int> vi[maxn];
int in[maxn];//in[n]代表第n個節點的入度 

int main(){
	int n;
	cin >> n;
	for(int i=1;i<=n;i++){
		int m;
		cin >> m;
		for(int j=0;j<m;j++){
			int x;
			cin >> x;
			vi[i].push_back(x);
			in[x]++;
		}
	}
	for(int i=1;i<=n;i++) cout << in[i] << " ";
	cout << endl;
    for(int i=1;i<=n;i++){//n,節點總數 
    	if(in[i]==0) q.push(i);//將入度爲0的點入隊 
	}
	int cnt=0;//操作次數 
    while(!q.empty())//遍歷隊列 
    {
        int p=q.front();//取出一個入度爲0的點 
		q.pop();
        for(int i=0;i<vi[p].size();i++)//將入度爲0的點所指向的點的入度減一 
        {
            int y=vi[p][i];
            in[y]--;
            if(in[y]==0){//如果剩下的點中出現入度爲0的點,將其入隊 
            	q.push(y); 
			}  
        }
        cnt++; 
    }
    //如果cnt==n,代表所有的節點都可以被分離出來,即不存在環 
    if(cnt==n) cout << 1 << endl; 
    else cout << 0 << endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章