poj 1094 拓扑排序(判断严格小于关系&判断是否有环)

Sorting It All Out
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 24933 Accepted: 8662

Description

An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

Input

Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

Output

For each problem instance, output consists of one line. This line should be one of the following three:

Sorted sequence determined after xxx relations: yyy...y.
Sorted sequence cannot be determined.
Inconsistency found after xxx relations.

where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence.

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.

Source

East Central North America 2001

这道题目考察了拓扑排序的基本思想:每一步寻找 一个入度为0的结点,然后删除之。将这个结点 指向的结点入度减1删除从这个结点出发的 所有边
同时考察了对于一个有向图是否有环、是否严格有序的判断。( 当发现多个结点的度为0时,则不是严格有序。当发现没有结点入度为0时,则有环
需要注意的是逻辑上的关系。“Sorted sequence cannot be determined.”这个判断,要放在最后,即只有发现了所有的点都没有环,且并没有发现严格有序性质的时候,才可以判为“Sorted sequence cannot be determined."
逻辑上的判决一定要注意优先级。
这个问题中优先级最高的是判断有环。一旦发现找不到度为0的结点,则立即return。
第二优先级是是否严格有序的判断。当每一步能且只能找到一个度为0的结点,则return。
第三优先级是无法确定。(当发现无法确定时,并不能立即return,因为还需要判断是否有环)

思维方式:问问自己,当条件x成立时,另外的条件y,z是否一定不成立。如果一定不成立,则可以断言return。否则必须继续判断下去。



提交记录:
1.样例未过! 由于拓扑排序算法中,处理过程中入度减1的同时,并没有将 对应的边删掉
2.样例未过! 由于在子函数judge中,对graph图进行了修改,导致后面处理失败。增加了memcpy解决。
3.segmentation fault! 当判断为1或者2的时候,不能立即break。因为后面还有输入,需要读入。修改为continue解决。
4.wrong answer! 在judge函数中,当出现多个结点度为0的时候,还需要继续判冲突,而不能直接return.
5.AC! 代码如下:

#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
         
         
#include 
         
         
           #include 
          
            using namespace std; int n, m; int graph[30][30]; queue 
           
             result_q; int judge() { int graph1[30][30]; memcpy(graph1, graph, sizeof(graph)); int i, j; int in[30] = {0}; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (graph1[i][j] == 1) { in[j] ++; } } } int k; queue 
            
              q; int flag = 0; for (k = 0; k < n; ) { int count = 0; for (i = 0; i < n; i++) { if (in[i] == 0) count++;//先计数! } if (count == 0) return 2; //没有找到入度为0的点,说明有环。高优先级判断 if (count > 1) flag = 3; //有多个点的入度为0, 严格的小于关系无法确定 //这里不可以 return。因为可能这个图依然是有环的。 for (i = 0; i < n; i++) { if (in[i] == 0) { k++; q.push(i); for (int j = 0; j < n; j++) { if (graph1[i][j]) { in[j]--; //除了减少入度,还要删边.注意这里会对外层循环的结果造成影响 graph1[i][j] = 0; //删边 } } in[i] = -1; break; //注意,一步只能删除一个点 } } } if (flag != 3) { result_q = q; return 1; } else return 3; } int main() { while (cin >> n >> m) { if (n == 0 && m == 0) { break; } int i, j; char left, right; memset(graph, 0, sizeof(graph)); int flag = 0; for (i = 1; i <= m; i++) { cin >> left >> right >> right; graph[left-'A'][right-'A'] = 1; if (flag == 1 || flag == 2) continue; flag = judge(); if (flag == 1) { cout << "Sorted sequence determined after " << i << " relations: "; while (!result_q.empty()) { int a = result_q.front(); result_q.pop(); cout << (char)('A' + a); } cout << "." << endl; } else if (flag == 2) { cout << "Inconsistency found after " << i << " relations." << endl; } } if (flag == 3) cout << "Sorted sequence cannot be determined." << endl; } return 0; } 
             
            
           
         
        
        
       
       
      
      
     
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值