POJ1094---Sorting It All Out

简介: POJ1094---Sorting It All Out

题目描述


不同值的升序排序序列是使用某种形式的小于运算符将元素从最小到最大排序的序列。例如,排序的序列 A, B, C, D 意味着 A < B, B < C 和 C < D. 在这个问题中,我们会给你一组 A < B 形式的关系,并要求你确定是否已指定排序顺序。


输入

输入由多个问题实例组成。每个实例以一行包含两个正整数 n 和 m 开始。第一个值表示要排序的对象数,其中 2 <= n <= 26。要排序的对象将是大写字母的前 n 个字符。第二个值 m 表示将在此问题实例中给出的 A < B 形式的关系数。接下来将是 m 行,每行包含一个这样的关系,由三个字符组成:一个大写字母、字符“<”和第二个大写字母。没有字母会超出字母表的前 n 个字母的范围。 n = m = 0 的值表示输入结束。


输出

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

xxx 关系后确定的排序顺序:yyy…y。

无法确定排序顺序。

xxx 关系后发现不一致。

其中 xxx 是确定排序序列或发现不一致时处理的关系数,以先到者为准,yyy…y 是排序的升序序列。


输入样例


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


输出样例


Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.


思路:这个题的意思是给你一些点之间的关系,然后边输入边进行判断,结果分为有序,无序,无法确定这三种情况.


当入度为0的顶点个数为0,说明有环,拓扑排序后,拓扑序列中点的个数小于n也说明有环,这种情况就是无序.

如果在拓扑排序的过程中,如果入度为0的顶点个数 > 1,则无法确定. 这种情况的结果就是无法确定.

除了以上两种,就是拓扑有序的,最后输出拓扑序列即可.

注意:

如果数据没有处理完就得到了结果,此时不能直接break,应该继续输入,否则进入下一个测试案例就会读入剩下的数据.


数据输入完毕之前是不能直接判断 结果是无法确定的. ,因为后序的数据可能会对前面的数据进行补充.


这个题的细节需要注意很多.


参考代码

#include<iostream>
#include<stack>
#include<string.h>
#include<string>
using namespace std;
const int maxn = 30;
int map[maxn][maxn], indegree[maxn], temp[maxn], topo[maxn], n, flag, idx;//temp:每个Case拓扑排序中的临时入度数组 flag:用于标记TopoSort后的状态.
string str;//用于接收点关系的字符串. 
int TopoSort() {
  //数据的初始化
  memset(temp, 0, sizeof(temp));
  memset(topo, 0, sizeof(topo));
  flag = 1;
  stack<int> s;
  int cnt = 0;//用于计数入度为0的点的个数,如果>1则将其状态置为-1(待定)  ==>因为后面的条件可能会让当前装填发生改变.
  for (int i = 1; i <= n; i++) {//temp数组进行初始化. 
    temp[i] = indegree[i];
    if (!temp[i]) {
      cnt++;
      s.push(i);//将入度为0的入栈. 
    }
  }
  if (cnt > 1) {
    flag = -1;
  }
  if (cnt == 0) {//如果没有入度为0的点则说明必定存在环. 
    flag = 0;
    return flag;
  }
  idx = 0;//用于控制topo序列的下标. 
  while (!s.empty()) {
    cnt = 0;//此处的cnt仍然用于计数,统计入度为0的点的个数. 
    int u = s.top();
    s.pop();
    topo[++idx] = u;//加入拓扑序列 
    for (int i = 1; i <= n; i++) {
      if (map[u][i]) {
        temp[i]--;
        if (!temp[i]) {
          s.push(i);
          cnt++;
        }
      }
    }
    if (cnt > 1) {
      flag = -1;
    }
  }
  if (idx < n) {//如果拓扑序列中的点小于总的点数则说明有环. 
    flag = 0;
    return flag;
  }
  return flag;
}
int main()
{
  int m, flag2, first, second, res;//flag2用于控制TopoSort是否执行,如果已经得到了结果则本轮只需要录入数据不需后序操作. 
  while (cin >> n >> m && n && m) {
    //数据初始化 
    memset(map, 0, sizeof(map));
    memset(indegree, 0, sizeof(indegree));
    res = 0;
    flag2 = 0;
    for (int i = 1; i <= m; i++) {//初始化indegree 
      cin >> str;
      if (flag2) {//后序不再执行 
        continue;
      }
      first = str[0] - 'A' + 1;
      second = str[2] - 'A' + 1;
      if (!map[first][second]) {//如果有重边,则只初始化一次.
        map[first][second] = 1;
        indegree[second]++;
      }
      if (first == second) {  //如果数据中有自环 如 A>A,则直接进行输出判断.
        cout << "Inconsistency found after " << i << " relations." << endl;
        flag2 = 1;
        continue;
      }
      res = TopoSort();//执行拓扑排序
      if (res == 0) {//说明存在环,则结果已经得到. 
        cout << "Inconsistency found after " << i << " relations." << endl;
        flag2 = 1;
      }
      else if (res == 1) {//说明拓扑排序列已找到. 
        cout << "Sorted sequence determined after " << i << " relations: ";
        for (int j = 1; j <= n; j++) {
          cout << char(topo[j] - 1 + 'A');
        }
        cout << "." << endl;
        flag2 = 1;
      }
      else if (res == -1 && i == m) //如果是-1则关系待定,继续进行判断. 
      {
      }
    }
    if (!flag2) {
      cout << "Sorted sequence cannot be determined." << endl;
    }
  }
  return 0;
}
相关文章
|
8月前
|
C++ 容器
POJ3096—Surprising Strings
POJ3096—Surprising Strings
|
C++
poj 2182 Lost Cows(树状数组)
FJ有n头牛,现在它们排成一排,每一头牛都有一个不同的编号(1-n),现在知道从第二头牛开始每头牛左边比自己编号小的牛的数目,让你确定每头牛的编号。
48 0
|
机器学习/深度学习
poj 2155 Matrix (二维树状数组)
这是楼教主出的二维线段树或者是二维树状数组的题,题意很简单,就是有个n*n的矩阵,初始值都是0,然后给你两个操作,一个是给你左上角和右下角的坐标,把这个长方形的区间所有元素反取反(0变1 1变0),另一个是求某个具体坐标的值。 这里我用了二维的线树状数组,一维树状数组可以解决区间更新和点查询的问题,这里只需要加一维就可以了,代码比较好写,不过开始犯了很多低级的错误。
52 0
|
算法
POJ3061 Subsequence
POJ3061 Subsequence
|
网络架构
POJ 3250 Bad Hair Day、POJ 2796 Feel Good(单调栈)
POJ 3250 Bad Hair Day、POJ 2796 Feel Good(单调栈)
POJ 3494 Largest Submatrix of All 1’s(单调栈)
POJ 3494 Largest Submatrix of All 1’s(单调栈)
|
索引
LeetCode 392. Is Subsequence
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
112 0
LeetCode 392. Is Subsequence
|
存储 C语言
POJ1521---Entropy
POJ1521---Entropy
|
算法
Bellman-Ford
笔记
84 0