poj 1094 / zoj 1060 Sorting It All Out


Sorting It All Out

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 26876   Accepted: 9271

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

[Submit]   [Go Back]   [Status]   [Discuss]

解题思路:这题是一个拓扑排序问题,不过过程比较复杂,要处理的情况也比较多!首先题目条件和要求要很清楚,这样分析问题思路就会清晰!

解题代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 using namespace std;
  5 struct Node{            //与之相连的节点结构体
  6     int to;
  7     struct Node *next;
  8 };
  9 Node *Link[27]; //链表保存连接关系
 10 Node *tm_node;
 11 bool vis[27];
 12 int count[27], tm_count[27]; //保存节点入度数据,前者为备份数据,后者为运算数据
 13 int n, m, num;
 14 char deal[3];
 15 const int A = ‘A‘;
 16 int result[27], pos; //保存结果
 17
 18 int TopSort(){
 19     int i, j, cnt;
 20     bool flag = false;
 21     pos = cnt = 0;// cnt为入度为0的节点数,pos为保存结果的下标
 22     j = -1; //入度为0的字母
 23     for (i = 0; i < n; i ++) //寻找入度为0的位置
 24         if(tm_count[i] == 0 && vis[i]){
 25             cnt ++;
 26             j = i;
 27         }
 28     while (~j){
 29         if(cnt > 1) //如果cnt > 1 则表示有多个入度为0的节点,也就是说可能无法排序
 30             flag = true; //不直接return是因为还有可能图中有环,导致数据矛盾
 31         for (tm_node = Link[j]; tm_node != NULL; tm_node = tm_node ->next)
 32             tm_count[tm_node ->to] --;
 33         result[pos ++] = j;
 34         tm_count[j] --;
 35         j = -1;
 36         cnt = 0;
 37         for (i = 0; i < n; i ++)
 38             if(tm_count[i] == 0 && vis[i]){
 39                 cnt ++;
 40                 j = i;
 41             }
 42     }
 43     if(!flag && pos != num) // 图中有环,数据矛盾
 44         return -1;
 45     if(!flag && pos == num) //图中为一个有序序列,是否是最终结果还需进一步判断
 46         return 0;
 47     if(flag && pos == num)  //图中有多个有序序列,还需进一步判断
 48         return 1;
 49     if(flag && pos != num)  //图中有环,数据矛盾
 50         return -1;
 51 }
 52
 53 void init(){
 54     num = 0;
 55     memset(vis, 0, sizeof(vis));
 56     memset(Link, 0, sizeof(Link));
 57     memset(count, 0, sizeof(count));
 58     memset(tm_count, 0, sizeof(tm_count));
 59 }
 60
 61 void input(){
 62     int d1, d2;
 63     scanf("%s", deal);
 64     d1 = deal[0] - A;
 65     d2 = deal[2] - A;
 66     tm_node = new Node;
 67     tm_node ->next = NULL;
 68     tm_node ->to = d2;
 69     count[d2] ++;
 70     if(Link[d1] == NULL)
 71         Link[d1] = tm_node;
 72     else{
 73         tm_node ->next = Link[d1];
 74         Link[d1] = tm_node;
 75     }
 76     if(vis[d1] == 0){
 77         num ++;
 78         vis[d1] = true;
 79     }
 80     if(vis[d2] == 0){
 81         num ++;
 82         vis[d2] = true;
 83     }
 84 }
 85
 86 int main(){
 87     int i, j;
 88     int value;
 89     bool had_ans;
 90     while(~scanf("%d%d", &n, &m) && (n && m)){
 91         init(); //初始化
 92         had_ans = false; //是否已经得出结果
 93         for(i = 1; i <= m; i ++){
 94             if(had_ans){  //如果已有结果,则无须处理后续数据
 95                 scanf("%s", deal);
 96                 continue;
 97             }
 98             input(); //数据处理
 99             for(j = 0; j < n; j ++)
100                 tm_count[j] = count[j];
101             value = TopSort(); //拓扑排序
102             if (value == -1){
103                 printf ("Inconsistency found after %d relations.\n", i);
104                 had_ans = true;
105             }
106             else if(value == 0 && num == n){ //数据量以满足要求,且能排序
107                 printf ("Sorted sequence determined after %d relations: ", i);
108                     for (j = 0; j < n; j ++)
109                         printf ("%c", result[j] + A);
110                 printf(".\n");
111                 had_ans = true;
112             }
113         }
114         if (value == 1 || (value == 0 && n != num)) // 无法排序
115             printf("Sorted sequence cannot be determined.\n");
116     }
117     return 0;
118 }

poj 1094 / zoj 1060 Sorting It All Out

时间: 2024-08-28 16:17:33

poj 1094 / zoj 1060 Sorting It All Out的相关文章

zoj 1060 Sorting It All Out

这题题目的意思我跟hdu的确定比赛名次的要求搞混了,其实很容易. 确定比赛名次的题意是在不确定顺序的时候,不能确定的顺序按照字母升序排列 这边给出一些大小关系,而你的任务就是理清这些关系. 然后就有一个全序,偏序的概念. 具体的理论部分可以见:http://blog.csdn.net/dm_vincent/article/details/7714519 要注意的就是题目中的要求是 环和全序得出结论后,就不再进行后面数据的处理. 在不确定顺序的情况下,环是可以存在的. 1 #include <st

zoj 1060 Sorting It All Out(拓扑排序)

#include<bits/stdc++.h> using namespace std; vector< vector<char> >v; int n,m,use[30],cnt[30]; char ans[30],s[10]; int topsort(int x) { int i,j,t[30],f=1,r,c; memset(ans,0,sizeof(ans)); for(i=0; i<30; i++) t[i]=cnt[i]; c=0; r=0; while

拓扑序列变形 之 poj 1094 Sorting It All Out

/* 拓扑序列变形 之 poj 1094 Sorting It All Out 变形: 在每消去唯一一个入度为0的点后,只剩下唯一一个入度为0的点. 这样获得的n个点才是排序好的. */ 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstddef> 5 #include <iterator> 6 #include <algorithm&

【POJ 1094】Sorting It All Out

[POJ 1094]Sorting It All Out 拓扑排序 输出第一次成功排序的位置及顺序(能顺利拓扑并在拓扑中不存在同级) 或者 第一个出现与之前给出条件相悖的位置(拓扑过程中出现间断) 坑点是出现任何一种情况就out 代码如下 #include <iostream> using namespace std; int in[26],inn[26],n; int mp[26][26]; int Topo(int op) { int i,j,k,f = 1; for(i = 0; i &

poj 1094 Sorting It All Out 解题报告

题目链接:http://poj.org/problem?id=1094 题目意思:给出 n 个待排序的字母 和 m 种关系,问需要读到第 几 行可以确定这些字母的排列顺序或者有矛盾的地方,又或者虽然具体的字母顺序不能确定但至少不矛盾.这些关系均是这样的一种形式: 字母1 < 字母2 这道题目属于图论上的拓扑排序,由于要知道读入第几行可以确定具体的顺序,所以每次读入都需要进行拓扑排序来检验,这时每个点的入度就需要存储起来,所以就有了代码中memcpy 的使用了. 拓扑排序的思路很容易理解,但写起来

poj 1979 &amp;&amp; zoj 2165 Red and Black

Red and Black Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22409   Accepted: 12100 Description There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a

poj 1094

唉  这几天有点热 有点烦躁 以后能做成什么样.... 题意:给定n个字母<0+A,...n+A> 和m个关系 想x>y  问是否能唯一确定他们的大小关系 1  在第几个关系能确定他们的排序 就输出这个位置和排序 2 如果出现矛盾就输出矛盾的位置 3 整个关系输入之后还不能确定则输出不能确定关系 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

Poj 1094 拓扑排序 水题

Sad..这么水的题WA了无数发,题目要看仔细啊,留下来做个警告把 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #i

POJ 1128 &amp; ZOJ 1083 Frame Stacking (拓扑排序)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=83 http://poj.org/problem?id=1128 Frame Stacking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4102   Accepted: 1378 Description Consider the following 5 picture frames placed