POJ 1094 Sorting It All Out

来源:互联网 发布:贾真的淘宝店 编辑:程序博客网 时间:2024/05/21 22:49

题目大意:

        现有多个测例,每个测例都会给定一个序列长度n(2 ≤ n ≤ 26),序列有大写字母的前n个字母组成,接下来给定m个关系约束,每个关系由小于号规定,形式比如为"A < B",每读一个关系就要判断该序列是否能确定或者是否前后矛盾(比如前面的关系能推出A < B,后面的关系又能推出A > B),如果能确定出序列就要输出经过多少条关系后能确定出此序列,并且打印出该序列,如果推出前后矛盾,也要输出是经过多少条关系推出了前后矛盾这个结论,如果经过所有关系后也不能确定出该序列或者推出前后矛盾,就输出该序列无法确定的信息,输入的关系中的字母保证多处于前n个大写字母的范围,测例以n, m = 0表示结束。

题目链接

注释代码:

/*                                * Problem ID : POJ 1094 Sorting It All Out * Author     : Lirx.t.Una                                * Language   : C++                    * Run Time   : 16 ms                                * Run Memory : 180 KB                               */ #include <iostream>#include <cstring>#include <cstdio>#include <queue>//序列最大长度#defineMAXN26using namespace std;chardeg[MAXN];//degree,入度chartmp_deg[MAXN];//临时空间,可以存放deg副本boolg[MAXN][MAXN];//graph,存放序列中各个元素之间的关系charfmt[4];//临时接受输入的字符串queue<char>ord;//存放最终确定下来的序列inttopsort( int n, char *deg ) {//拓扑排序//n为序列的长度//deg,入度信息inti;//计数变量intu, v;//点boolnosure;//标记序列是否是不确定的(就是拓扑排序会产生多种情况)queue<char>que;//存放入度为0的点//上次排序可能不成功,有上次的信息留在ord中,需要清空不影响本次排序while ( !ord.empty() ) ord.pop();for ( i = 0; i < n; i++ )//找出所有入度为0的点存放到que中if ( !deg[i] ) que.push(i);nosure = false;//将不确定标记置为falsewhile ( !que.empty() ) {//如果在去0入度点时有多个,就意味着拓扑排序的情况有多种if ( que.size() > 1 ) nosure = true;//将情况置为不确定//!!但是不确定并不意味着检查可以结束,因为可能会出现前后矛盾的情况//随着关系的增多不确定可能会转化为确定,但是一旦发现矛盾的情况就//应该立即对本次测例给出判断结论了ord.push((u = que.front()) + 'A');//暂且将该点放入ord中,如果最终不确定不输出就行了que.pop();for ( v = 0; v < n; v++ )//将所有与之相连的点的入度都-1,并且如果-1后为0就如队if ( g[u][v] && !(--deg[v]) )que.push(v);}//如果仍然有部分点入度不为0则表示有环,即出现了前后矛盾的情况if ( ord.size() < n ) return 'I';//比如A > B > C > A,这就矛盾了,并返回(I)nconsistency标记if ( nosure ) return 'N';//虽然不矛盾但是不确定(即有多种情况,序列不能唯一确定),返回(N)ot sure标记return 'D';//序列被唯一确定下来了,返回(D)etermained标记}intmain() {intn, m;//序列长度,关系数intu, v;//点intstp;//表示经过多少步得出结论inti;//计数变量boolincn, detm;//inconsistency and determained,标记是否矛盾或者被唯一确定while ( scanf("%d%d", &n, &m), n ) {//初始化incn = false;detm = false;memset(g, false, sizeof(g));memset(deg, 0, sizeof(deg));for ( i = 1; i <= m; i++ ) {scanf("%s", fmt);if ( incn || detm ) continue;//如果两者中有一个被确定则不必再检查//虽然已经判断出来了但是也要把剩余的关系读完u = fmt[0] - 'A';//映射成数组下标v = fmt[2] - 'A';if ( g[v][u] ) {//如果存在反向边则可以直接判断出冲突incn = true;stp  = i;//记录关系数量continue;}if ( g[u][v] ) continue;//表示该关系重复输入//更新边和入度g[u][v] = true;deg[v]++;memcpy(tmp_deg, deg, sizeof(deg));switch ( topsort( n, tmp_deg ) ) {//拓扑排序case 'D' : detm = true;stp  = i;break;case 'I' : incn = true;stp  = i;break;default  : break;//未确定,还需等待下次关系输入后判断}}if ( detm ) {//关系都输完后得出结论printf("Sorted sequence determined after %d relations: ", stp);while ( !ord.empty() ) {putchar(ord.front());ord.pop();}puts(".");}else if ( incn )printf("Inconsistency found after %d relations.\n", stp);else//即不矛盾也没有确定,那就是没确定puts("Sorted sequence cannot be determined.");}return 0;}
无注释代码:

#include <iostream>#include <cstring>#include <cstdio>#include <queue>#defineMAXN26using namespace std;chardeg[MAXN];chartmp_deg[MAXN];boolg[MAXN][MAXN];charfmt[4];queue<char>ord;inttopsort( int n, char *deg ) {inti;intu, v;boolnosure;queue<char>que;while ( !ord.empty() ) ord.pop();for ( i = 0; i < n; i++ )if ( !deg[i] ) que.push(i);nosure = false;while ( !que.empty() ) {if ( que.size() > 1 ) nosure = true;ord.push((u = que.front()) + 'A');que.pop();for ( v = 0; v < n; v++ )if ( g[u][v] && !(--deg[v]) )que.push(v);}if ( ord.size() < n ) return 'I';if ( nosure ) return 'N';return 'D';}intmain() {intn, m;intu, v;intstp;inti;boolincn, detm;while ( scanf("%d%d", &n, &m), n ) {incn = false;detm = false;memset(g, false, sizeof(g));memset(deg, 0, sizeof(deg));for ( i = 1; i <= m; i++ ) {scanf("%s", fmt);if ( incn || detm ) continue;u = fmt[0] - 'A';v = fmt[2] - 'A';if ( g[v][u] ) {incn = true;stp  = i;continue;}if ( g[u][v] ) continue;g[u][v] = true;deg[v]++;memcpy(tmp_deg, deg, sizeof(deg));switch ( topsort( n, tmp_deg ) ) {case 'D' : detm = true;stp  = i;break;case 'I' : incn = true;stp  = i;break;default  : break;}}if ( detm ) {printf("Sorted sequence determined after %d relations: ", stp);while ( !ord.empty() ) {putchar(ord.front());ord.pop();}puts(".");}else if ( incn )printf("Inconsistency found after %d relations.\n", stp);elseputs("Sorted sequence cannot be determined.");}return 0;}

0 0
原创粉丝点击