poj1094 好一个拓扑排序

/*
拓扑排序,注意一些变态的例子
1.该字母序列有序,并依次输出;
2.该序列不能判断是否有序;
3.该序列字母次序之间有矛盾,即有环存在。
而这三种形式的判断是有顺序的:先判断是否有环(3),再判断是否有序(1),最后才能判断是否能得出结果(2)。
注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。
*/
#include<iostream>
#include<cstring>
using namespace std;
int map[27][27], indegree[27], q[27];
int TopoSort(int n) //拓扑排序
{
	int c = 0, temp[27], indx, m, flag = 1, i, j;  flag=1:有序 flag=-1:不确定
	for (i = 1; i <= n; i++)
		temp[i] = indegree[i];
	for (i = 1; i <= n; i++)
	{
		m = 0;
		for (j = 1; j <= n; j++)
		{
			if (temp[j] == 0) //每次更新图后,查找入度为零的顶点个数
			{
				m++;
				indx = j;
			}
		}
		if (m == 0) return 0;  //有环
		if (m>1)    flag=-1;  // 这里一定要注意!!!,无序,只有每次只是出现一个入度为0时,才能排成序
		q[c++] = indx;   //入度为零的点入队
		temp[indx] = -1;
		for (j = 1; j <= n; j++)
		{
			if (map[indx][j] == 1)
			{
				temp[j]--;
			}
		}
	}
	return flag;
}
int main()
{
	int m=0, n=0, i=0, sign=0;  //当sign=1时,已得出结果
	char str[5] = { '\0' };
	while (1)
	{
		cin >> n>> m;
		if (n== 0 && m== 0) break;
		memset(map, 0, sizeof(map));
		memset(indegree, 0, sizeof(indegree));
		sign = 0;
		for (i = 1; i <= m; i++)
		{
			cin >> str;
			if (sign) continue; //一旦得出结果,对后续的输入不做处理
			int x = str[0] - 'A' + 1;
			int y = str[2] - 'A' + 1;
			map[x][y] = 1;
			indegree[y]++;
			int s = TopoSort(n);
			if (s == 0) //有环
			{
				printf("Inconsistency found after %d relations.\n", i);
				sign = 1;
			}
			if (s == 1) //有序
			{
				printf("Sorted sequence determined after %d relations: ", i);
				for (int j = 0; j<n; j++)
					printf("%c", q[j] + 'A' - 1);
				printf(".\n");
				sign = 1;
			}
		}
		if (!sign) //不确定
			printf("Sorted sequence cannot be determined.\n");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值