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;
}
发布了10 篇原创文章 · 获赞 7 · 访问量 159

猜你喜欢

转载自blog.csdn.net/qq_44204959/article/details/104683361
今日推荐