题意:给出大于等于 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, flag; int result[27]; //拓扑排序结果存放数组 int visited[27]; //拓扑排序时标识是否已访问过 int map[27][27]; //map[i][j] = 1 表示从 i + 'A' 到 j + 'A' 之间有一条单向边 int in[27]; //in[i] 存放 i + 'A' 的入度 /检查是否有环 void floyd( int a, int b ){ int i, j, k; for( k = 0; k < n; k ++ ){ for( i = 0; i < n; i ++ ){ for( j = 0; j < n; j ++ ){ if( map[i][k] == 1 && map[k][j] == 1 ){ if( map[i][j] == 0 ){ map[i][j] = 1; in[j] ++; //注意入度的更新 } if( i == a && j == b ){ //发现有环 flag = 1; return; } } } } } } 拓扑排序 bool Toposort( ){ int i, j, k, size = 0; bool remark; int tmp[27]; //入度的副本 for( i = 0; i < 26; i ++ ) tmp[i] = in[i]; for( i = 0; i < n; i ++ ){ k = -1; remark = false; for( j = 0; j < n; j ++ ){ if( tmp[j] == 0 && !visited[j] ){ if( remark ) //入度为0的节点超过两个表示拓扑排序结果不唯一 return false; remark = true; k = j; } } if( k == -1 ) return false; result[size ++] = k; visited[k] = 1; 更新有从已排序的当前节点有单向边的节点的入度 for( j = 0; j < n; j ++ ){ if( map[k][j] == 1 ) tmp[j] --; } } return true; } int main() { int m, i, j; //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( map, 0, sizeof( map ) ); memset( in, 0, sizeof( in ) ); flag = 0; char a, b; for( i = 1; i <= m; i ++ ){ string s; cin>>s; a = s[0]; b = s[2]; if( flag == 0 ){ if( map[a - 'A'][b - 'A'] == 0 ){ map[a - 'A'][b - 'A'] = 1; in[b - 'A'] ++; } 检查是否有矛盾,即对环的检查 floyd( b - 'A', a - 'A' ); if( flag == 1 ) printf( "Inconsistency found after %d relations.\n", i ); else{ memset( visited, 0, sizeof( visited ) ); if( Toposort() ){ printf( "Sorted sequence determined after %d relations: ", i ); for( j = 0; j < n; j ++ ) printf("%c", result[j] + 'A'); printf(".\n"); flag = 1; } } } } if( flag == 0 ) printf("Sorted sequence cannot be determined.\n"); } //fclose(stdin); //fclose(stdout); return 0; }