poj_1094 拓扑排序

思路:

对于每一个case,每输入一个式子的时候都要判断一下这次的输入能否使当前case的n个字母有序,如果可以,不处理下面的输入。如何判断:构建图,初始每个顶点入度都为0,如果没有入度为0的点,说明有环,结束;如果目前输入的表达式含有的字母数没到n时,说明无序;否则看是否能建立拓扑排序,如果能输出拓扑排序结果;不能,输出cannot determined。


代码如下:

#include<iostream>
#include<fstream>

using namespace std;

int map[27][27];
int indegree[27],queue[27];

int toposort(int n)
{
	int flag=1,m,loc,count=0;
	int temp[27];
	for (int i = 1; i <= n; i++)
	{
		temp[i] = indegree[i];
	}
	for (int i = 1; i <= n; i++)
	{
		m = 0;//入度为0的顶点个数
		for (int j = 1; j <= n; j++)
		{
			if (temp[j] == 0)
			{
				m++;
				loc = j;
			}
		}
		if (m == 0) //没有入度为0的点,说明是环!
		{
			return 0;
		}
		if (m > 1) //入度为0的顶点个数>1,说明无序!
		{
			flag = -1;
		}
		queue[count++] = loc; //入度为0的顶点入队,每次去除一个入度为0的顶点
		temp[loc] = -1;
		for (int j = 1; j <= n; j++) //更新其它点入度信息
		{
			if (map[loc][j] == 1)
			{
				temp[j]--;
			}
		}
	}
	return flag;
}

int main()
{
	//ifstream in("input.txt");
	int n, m,success;
	char str[5];
	while (cin >> n >> m && n != 0 && m != 0)
	{
		memset(map,0,sizeof(map));
		memset(indegree,0,sizeof(indegree));
		success = 0;
		for (int i = 1; i <= m; i++)
		{
			cin >> str;
			if (success == 1)
				continue;
			int x = str[0] - 'A' + 1;
			int y = str[2] - 'A' + 1;
			map[x][y] = 1;
			indegree[y]++;
			int result = toposort(n);
			if (result==0) //如果是环,找到结果,退出!
			{
				cout << "Inconsistency found after " <<i<<" relations."<< endl;
				success = 1;
			}
			if (result == 1)
			{
				cout << "Sorted sequence determined after " << i << " relations: ";
				for (int j = 0; j < n; j++)
				{
					char c = queue[j] + 'A' - 1;
					cout << c;
				}
				cout <<"."<< endl;
				success = 1;
			}
		}
		if (success != 1)
		{
			cout << "Sorted sequence cannot be determined." << endl;
		}
	}
	//system("pause");
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值