poj 1094 之解法一 传递闭包

题目链接

题意:给出大于等于 A 小于 A +  n 的字母间的大小关系式,问是否能确定 n个字母的大小关系?如能,在第几个关系式时能确定?如不能,是否出现了矛盾,在第几个关系式时出现了矛盾?

关系式举例如下:

A<B
A<C
B<C
C<D
B<D
A<B
#include<stdio.h>
#include <stdlib.h>
#include <iostream>
#include<string>
using namespace std;
int n;
int in[27], out[27];   //各个节点的入度、出度
int map[27][27];	   //邻接矩阵表示节点间的边
int main()
{
	int  m, i, j, k, flag, n;
	//freopen("C:\\Users\\Administrator\\Desktop\\cincout\\1.txt", "r", stdin);
	//freopen("C:\\Users\\Administrator\\Desktop\\cincout\\2.txt", "w", stdout);
	while( scanf("%d%d", &n, &m ) && ( n || m ) ){	
		memset( in, 0, sizeof(in) );
		memset( out, 0, sizeof(out) );
		memset( map, 0, sizeof( map ) );
		flag  = 0;
		char a, b;
		for( i = 1; i <= m; i ++ ){
			string s;
			cin>>s;
			
			a = s[0]; b = s[2];

			if( flag == 0 ){
			 a - 'A' 与 b - 'A' 间添加一条单向边,同时更新两个节点的入度出度
				if( map[a - 'A'][b - 'A'] == 0 ){
					map[a - 'A'][b - 'A'] = 1;
					in[b - 'A'] ++;
					out[a - 'A'] ++;
				}
			将 a - 'A' 与所有以 b - 'A' 为起点的有单向边的节点连接 
				for( j = 0; j < n; j ++ ){
					if( map[b - 'A'][j] == 1 ){
						if( map[a - 'A'][j] == 0 ){
							map[a - 'A'][j] = 1;
							out[a - 'A'] ++;
							in[j] ++;
						}
					}
				}
			将所有以 a - 'A' 为终点的有单向边的节点与 b - 'A' 与连接 
				for( j = 0; j < n; j ++ ){
					if( map[j][a - 'A'] == 1 ){
						if( map[j][b - 'A'] == 0 ){
							map[j][b - 'A'] = 1;
							in[b - 'A'] ++;
							out[j] ++;
						}
					}
				}
			将所有以 a - 'A' 为终点的有单向边的节点与所有以 b - 'A'为起点的有单向边的节点连接 
				for( j = 0; j < n; j ++ ){
					if( map[j][a - 'A'] == 1 ){
						for( k = 0; k < n; k ++ ){
							if( map[b - 'A'][k] == 1 ){
								if( map[j][k] == 0 ){
									map[j][k] = 1;
									in[k] ++;
									out[j] ++;
								}
							}
						}
					}
				}
			检查是否有环
				if( map[b - 'A'][a - 'A'] == 1 ){
					printf( "Inconsistency found after %d relations.\n", i );
					flag = 1;
				}
				else{
					当每个节点的入度与出度和=(节点总数 - 1) 时,它们的拓扑排序的结果就是唯一的
					for( j = 0; j < n; j ++ ){
						if( in[j] + out[j] != n - 1 )
							break;
					}
					if( j == n ){
						printf( "Sorted sequence determined after %d relations: ", i );
						for( j = 0; j < n; j ++ )
							for( k = 0; k < n; k ++ )
								if( in[k] == j )
									printf("%c", k + 'A');
						printf(".\n");		
						flag = 1;
					}
				}
			}
		}									
		if( flag == 0 )
			printf("Sorted sequence cannot be determined.\n");	
	}
	//fclose(stdin);
	//fclose(stdout);	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值