poj1094 拓扑排序,栈+入度,方法很难想到,

//poj1094 拓扑排序 栈+入度
//若A比B,C,D小,A的度就是3.只要通过不断缩小B/C/D的度,然后减小A的度,当A的度是0的时候,就可以存进栈里面了
//题解的强大之处在于灵活利用了入度这个概念,存在解的时候,必须满足只有一个单源点,沿着解这条路走,必然是单源点后面跟着入度为1的点,
//然后删除单源点,更新入度,重复,又是仅有一个单源点,且后面跟着入度为1的点。最后仅剩一个单源点。
//有环的话,随着单源点的删除,最后会出现没有单源点的情况,这个时候就可以判读处理有环。
//无序的话,无论什么时候,出现多个单源点都说明无序。
#include <iostream>
using namespace std;
int map[31][31];
char in[4];
int stack[31];
int deg[31];
int top;
int TopSort(int n)
{
	int m = 0;
	int flag = 1;
	int rec = 0;
	top = 0;
	int temp[31];
	for (int i = 0; i < n; i++)
		temp[i] = deg[i];
 	for (int i = 0; i < n; i++)
	{
		m = 0;
		for (int j = 0; j < n; j++)
		{
			if (temp[j] == 0)
			{
				m++;
				rec = j;
			}
		}
		if (m == 0)
			return 0;
		if (m > 1)
			 flag = -1;
		stack[top++] = rec;
		temp[rec] = -1;
		for (int j = 0; j < n; j++)
		{
			if (map[rec][j] == 1)
				temp[j]--;
		}
	}
	return flag;
}
int main()
{
	int m, n;
	cin >> m >> n;
	while (m && n)
	{
		bool ok = false;
		memset(map, 0, sizeof(map));
		memset(stack, 0, sizeof(stack));
		memset(deg, 0, sizeof(deg));
		for (int i = 0; i < n; i++)
		{			
			cin >> in;
			if (ok)
				continue;
			int p1 = int(in[0] - 'A');
			int p2 = int(in[2] - 'A');
			map[p1][p2] = 1;
			deg[p2]++;
			int s = TopSort(m);
			if (s == 0)
			{
				cout << "Inconsistency found after " << i + 1 << " relations." << endl;
				ok = true;
			}
			else if (s == 1)
			{
				cout << "Sorted sequence determined after " << i + 1 << " relations: ";
				for (int j = 0; j < top; j++)
					cout <<char('A'+stack[j]);
				cout << "." << endl;
				ok = true;
			}
		}
		if (!ok)
			cout << "Sorted sequence cannot be determined." << endl;
		cin >> m >> n;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/chchlh/article/details/41846509