题意:给出大于等于 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; }