POJ-1094 -拓扑排序应用

http://poj.org/problem?id=1094

题目给出n,m表示有n个字母 要排序 A.B.C..D..前n个,

m条关系 X<Y 

在读入m条关系的过程中


情况【1】假如读到第i条时,可以用前i条边确定出 字典序前n个字母之前的大小关系,请输入序列,以及当前的i


情况【2】假如读到第i条时,可以用前i条边确定出 当前的边在一起是不可能构成一个有序序列,请输入当前的i,以及“不可能构成有序序列”


情况【3】假如读完了m条后,发现还没法确定  一个关于前n个字母有序的序列(少一个都不行),也暂时没造成矛盾,请输入 “不能准确判断”


解决方案:

把每次输入的关系看成一条有向边,map[u][v]=1;并且记下 点V的入度(拓扑排序用), 然后进行一次拓扑排序,

如果是情况【1】, 则输出情况1的答案;接下来直接读取完剩下的条件,不作处理;

如果是情况【2】,同上


如果是情况【3】,继续读入下一条边直到 m条边处理完;


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue> 
#include <set>
#include <vector>
using namespace std;
int map[28][28];
int indegree[28];
int cun=0;
int qq[28];
int mark;// 表示已经得到确定结果了,剩下的输入只需要读入不需要考虑

int Topo(int n)
{
	int i,j;
	int cun=0;
	int ret=1;  //0表示有环,-1表示无序,1表示有序
	int temp_du[28];  //a copy of indegree
	for (i=1;i<=n;i++)
		temp_du[i]=indegree[i];

	int zero=-1;// index of 度数为0的顶点
	for (i=1;i<=n;i++)
	{
		int num=0;  // num of 度数为0的顶点
		for (j=1;j<=n;j++)
		{
			if (temp_du[j]==0)
			{
				num++;
				zero=j;
			}
		}
		if (num==0) //有环
		return 0;
		if (num>1)  //仅仅指当前条边所得到的结果是无序的,可能再加一些边后得到有序或者 有环的结果
		{
			ret=-1; //0表示有环,-1表示无序,1表示有序
		}
		qq[cun++]=zero;  //度为0的点入队;
		temp_du[zero]=-1; // 删除该点;
		for (j=1;j<=n;j++)
		{
			if (map[zero][j]==1)
			{
				temp_du[j]--;
			}
		}
	}
return ret;
} 


char str[15];
int main()
{
	int n,m;
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if (!n&&!m) break;
		memset(map,0,sizeof(map));
		memset(indegree,0,sizeof(indegree));
		mark=0; //结束标记
		for (i=1;i<=m;i++)
		{
			scanf("%s",str);
			if (mark) continue;  //不用继续处理
			int u=str[0]-'A'+1;
			int v=str[2]-'A'+1;
			map[u][v]=1;
			indegree[v]++;
			int s=Topo(n);
			if (s==0) //有环,矛盾
			{
				printf("Inconsistency found after %d relations.\n",i);
				mark=1;  //以后的输入不再处理
			}
			if (s==1)
			{
				printf("Sorted sequence determined after %d relations: ",i);
				for (j=0;j<n;j++)
				{
					printf("%c",qq[j]+'A'-1);
				}
				printf(".\n");
				mark=1;
			} 
		}
		if (!mark) 
         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、付费专栏及课程。

余额充值