Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 26070 | Accepted: 9031 |
Description
Input
Output
Sample Input
4 6 A<B A<C B<C C<D B<D A<B 3 2 A<B B<A 26 1 A<Z 0 0
Sample Output
Sorted sequence determined after 4 relations: ABCD. Inconsistency found after 2 relations. Sorted sequence cannot be determined.
思路:
拓扑排序(堆栈);
需要记录的数据: 有向图(临界矩阵), 各点入度值,排序结果
先找入度为0的入栈,作为起点,放到栈顶;
再将与栈顶元素相连的点的入度减1、如果减1后有点入度为0,则入队;
类推,详见代码
代码:
#include <stdio.h> #include <string.h> #include <stack> #define N 30 using namespace std; int n, m; bool map[N][N]; int in[N], list[N]; int toposort() { int tin[N]; memcpy(tin, in, sizeof(in)); stack<int>q; for(int i = 0; i < n; i ++){ // 先找一个入度为1的点 if(!tin[i]){ q.push(i); } } int flag = 0, top, l_ct = 0; // flag 为路径唯一的标记, l_ct 为 list 数组的计数器 while(!q.empty()){ if(q.size() > 1) flag = 1; top = q.top(); q.pop(); list[l_ct ++] = top; for(int i = 0; i < n; i ++){ if(map[top][i]){ if(-- tin[i] == 0){ // 入度为1的点入栈 q.push(i); } } } } if(l_ct != n){ // 不能拓扑排序,既有环(必须先判断此项) return 1; } else if(flag == 1){ // 有多种排序方式 return 2; } return 0; // 成功 } int main() { char x, y; while(scanf("%d%d", &n, &m), n && m){ int failed = 0, sure = 0; // 已失败(有环), 已成功排序 memset(map, 0, sizeof(map)); memset(in, 0, sizeof(in)); memset(list, 0, sizeof(list)); for(int i = 1; i <= m; i ++){ scanf(" %c<%c", &x, &y); if(!failed && !sure){ if(map[y - 'A'][x - 'A']){ printf("Inconsistency found after %d relations.\n",i); failed = 1; continue; } if(map[x - 'A'][y - 'A'] == 0){ map[x - 'A'][y - 'A'] = 1; in[y - 'A'] ++; // y点入度加1 } int ans = toposort(); if(ans == 0){ printf("Sorted sequence determined after %d relations: ",i); for(int j = 0; j < n; j ++) printf("%c", 'A' + list[j]); printf(".\n"); sure = 1; } else if(ans == 1){ printf("Inconsistency found after %d relations.\n",i); failed = 1; } } } if(!failed && !sure){ // 即未成功也未失败,既无法判断 printf("Sorted sequence cannot be determined.\n"); } } return 0; }