【HDOJ 3342 Legal or Not】拓扑排序入门

版权声明: https://blog.csdn.net/leelitian3/article/details/82253523

关于拓扑排序的基础知识:算法导论第22章:基本的图算法

#include <iostream>
#include <iomanip>
#include <cstring>
#include <vector>
#include <list>
#include <stack>
using namespace std;

vector<list<int>> adj;		//邻接表 
stack<int> zero;			//当前入度为0的结点 
int deg[105];				//deg[i]保存结点i的入度 
vector<int> ans;			//拓扑序结果 

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n,m,a,b,cur;
	while(cin>>n>>m && n)
	{
		//初始化 
		memset(deg,0,sizeof(deg));
		adj.clear();
		ans.clear();
		adj.assign(n,list<int>());
	
		for(int i=0; i<m; ++i)
		{
			cin>>a>>b;
			adj[a].push_back(b);		//构建邻接表 
			++deg[b];					//计算每个结点的入度 
		}
		for(int i=0; i<n; ++i)
			if(deg[i]==0) zero.push(i);	//将入度为0的结点入栈 

		while(!zero.empty())			//删除入度为0的结点的出边,即减去相应结点的入度 
		{
			cur = zero.top();
			zero.pop();
			for(list<int>::iterator p = adj[cur].begin(); p != adj[cur].end(); ++p)
			{
				--deg[*p];
				if(deg[*p] == 0) zero.push(*p);
			}
			ans.push_back(cur);			//保存拓扑序 
		}
		
		cout<<(ans.size() == n ? "YES" : "NO")<<"\n";	//若存在环,则ans.size() < n 
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/82253523
今日推荐