全排序问题

x33g5p2x  于2022-07-19 转载在 其他  
字(2.3k)|赞(0)|评价(0)|浏览(398)

一 原问题链接

Sorting It All Out - POJ 1094 - Virtual Judge

https://vjudge.net/problem/POJ-1094

二 输入和输出

1 输入

输入包含多个测试用例。每个测试用例的第 1 行都包含两个正整数 n 和 m。n 表示要排序的对象数量,排序的对象是大写字母的前 n 个字符。m 表示给出的 A<B 形式的关系数量。接下来的 m 行,每行都包含一种由 3 个字符组成的关系:第 1 个大写字母、字符 < 和第 2 个大写字母。n=m=0的值表示输入结束。

2 输出

对于每个问题实例,其输出都由一行组成,该行应该是以下三种之一。

  • 在 x 种关系之后确定的排序顺序:yyy..y。
  • 无法确定排序顺序。
  • 在 x 种关系后发现不一致。

其中,x 是在确定排序序列或找到不一致时处理的关系数,以先到者为准,yyy...y 是已排序的升序序列。

三 输入和输出样例

1 输入样例

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

2 输出样例

Sorted sequence determined after 4 relations: ABCD.

Inconsistency found after 2 relations.

Sorted sequence cannot be determined.

四 分析

本问题中,一边进行输入,一边进行判断,分为有序、无序、无法确定三种情况,可以利用拓扑排序进行判断。

五  算法设计

1 如果入度为 0 的节点个数为 0,则说明有环;如果拓扑序列节点数小于 n,则也说明有环。此情况无序。

2 如果入度为 0 的节点个数大于1,则无法确定,因为拓扑排序不唯一。

3 否则是拓扑有序,输入拓扑序列。

六 代码

  1. package graph.poj3687;
  2. import java.util.Scanner;
  3. import java.util.Stack;
  4. public class Poj1094 {
  5. static final int maxn = 27;
  6. static int map[][];
  7. static int indegree[];
  8. static int topo[];
  9. static int temp[];
  10. static int n;
  11. // flag=1:有序 flag=-1:不确定
  12. static int flag;
  13. static Stack<Integer> s = new Stack<>();
  14. static int TopoSort(int n) { //拓扑排序
  15. flag = 1;
  16. for (int i = 1; i <= n; i++)
  17. temp[i] = indegree[i];//一边输入一边拓扑排序,所有入度数组不能改变
  18. int m = 0, cnt = 0;
  19. for (int i = 1; i <= n; i++)//查找入度为零的顶点个数,若>1,拓扑序不确定
  20. if (temp[i] == 0) {
  21. s.push(i);
  22. cnt++;
  23. }
  24. if (cnt == 0) return 0; //有环
  25. if (cnt > 1) flag = -1; //不确定
  26. while (!s.empty()) {
  27. cnt = 0;
  28. int i = s.peek();
  29. s.pop();
  30. topo[m++] = i;
  31. for (int j = 1; j <= n; j++)
  32. if (map[i][j] == 1) {
  33. temp[j]--;
  34. if (temp[j] == 0) {
  35. s.push(j);
  36. cnt++;
  37. }
  38. }
  39. if (cnt > 1) flag = -1;//不确定
  40. }
  41. if (m < n)//有环
  42. return 0;
  43. return flag;
  44. }
  45. public static void main(String[] args) {
  46. int m, n;
  47. boolean sign; // 当sign = true 时,已得出结果
  48. String str;
  49. Scanner scanner = new Scanner(System.in);
  50. while (true) {
  51. map = new int[maxn][maxn];
  52. indegree = new int[maxn];
  53. topo = new int[maxn];
  54. temp = new int[maxn];
  55. n = scanner.nextInt();
  56. m = scanner.nextInt();
  57. if (m == 0 && n == 0) break;
  58. sign = false;
  59. for (int i = 1; i <= m; i++) {
  60. str = scanner.next();
  61. if (sign) continue; //一旦得出结果,对后续的输入不做处理
  62. int x = str.charAt(0) - 'A' + 1;
  63. int y = str.charAt(2) - 'A' + 1;
  64. map[x][y] = 1;
  65. indegree[y]++;
  66. int s = TopoSort(n);
  67. if (s == 0) { // 有环
  68. System.out.printf("Inconsistency found after %d relations.\n", i);
  69. sign = true;
  70. } else if (s == 1) { //有序
  71. System.out.printf("Sorted sequence determined after %d relations: ", i);
  72. for (int j = 0; j < n; j++)
  73. System.out.print((topo[j] + 'A' - 1));
  74. System.out.printf(".\n");
  75. sign = true;
  76. }
  77. }
  78. if (!sign) // 不确定
  79. System.out.print("Sorted sequence cannot be determined.\n");
  80. }
  81. }
  82. }

七 测试

相关文章