P1347 排序

题目描述

一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D。在这道题中,我们将给你一系列形如A<B的关系,并要求你判断是否能够根据这些关系确定这个数列的顺序。

输入输出格式

输入格式:

第一行有两个整数n,m,n表示需要排序的元素数量,2<=n<=26,第1到n个元素将用大写的A,B,C,D....表示。m表示将给出的形如A<B的关系的数量。

接下来有m行,每行有3个字符,分别为一个大写字母,一个<符号,一个大写字母,表示两个元素之间的关系。

输出格式:

若根据前x个关系即可确定这n个元素的顺序yyy..y(如ABC),输出

Sorted sequence determined after xxx relations: yyy...y.

若根据前x个关系即发现存在矛盾(如A<B,B<C,C<A),输出

Inconsistency found after 2 relations.

若根据这m个关系无法确定这n个元素的顺序,输出

Sorted sequence cannot be determined.

(提示:确定n个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况)

输入输出样例

输入样例#1:

  1. 4 6
  2. A<B
  3. A<C
  4. B<C
  5. C<D
  6. B<D
  7. A<B
输出样例#1:

  1. Sorted sequence determined after 4 relations: ABCD.
输入样例#2:

  1. 3 2
  2. A<B
  3. B<A
输出样例#2:

  1. Inconsistency found after 2 relations.
输入样例#3:

  1. 26 1
  2. A<Z
输出样例#3:

  1. Sorted sequence cannot be determined

这道题我来提供一种tarjan+拓扑排序的做法,首先我们考虑满足第二种情况的序列,如果存在矛盾,那么这个图中一定存在环,这样我们就可以用tarjan缩点判断一下是否存在环,有一点需要注意,就是如果小于号两边的数相同,那么就一定产生矛盾(非常坑)。对于第一种情况的序列,不难看出这个序列的拓扑序一定是唯一的,而且一定不存在环,也就是说每次拓扑时在栈中的元素一定只有唯一的一个,这样只需在每次拓扑开始时判断一下元素个数即可。如果第一和第二种情况均不满足,那么一定就是第三种情况咯。

最后附上代码:

  1. #include<iostream>
  2. #include<string>
  3. #include<cmath>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<stack>
  7. #define maxn 1005
  8. using namespace std;
  9.  
  10. struct edge
  11. {
  12. int next;
  13. int to;
  14. }g[maxn<<];
  15. int n,m,num,col,tot,cnt,pd,cnt2,cc,pd1;
  16. int last[maxn],de[maxn],dfn[maxn],low[maxn],co[maxn],de1[maxn];
  17. char aa[],bb[maxn];
  18. stack<int>s;
  19. stack<int>ss;
  20.  
  21. void add(int from,int to)
  22. {
  23. g[++num].next=last[from];
  24. g[num].to=to;
  25. last[from]=num;
  26. }
  27.  
  28. void topo()
  29. {
  30. for(int i=;i<=n;i++)
  31. {
  32. if(de1[i]==)
  33. {
  34. ss.push(i);
  35. }
  36. }
  37. while(ss.size())
  38. {
  39. if(ss.size()>)//如果栈中多余一个元素,说明topo序不唯一
  40. {
  41. pd1=;
  42. break;
  43. }
  44. int u=ss.top();ss.pop();
  45. bb[++cc]=char(u+'A'-);
  46. for(int i=last[u];i;i=g[i].next)
  47. {
  48. int v=g[i].to;
  49. de1[v]--;
  50. if(de1[v]==)
  51. {
  52. ss.push(v);
  53. }
  54. }
  55. }
  56. }
  57.  
  58. void tarjan(int u)
  59. {
  60. dfn[u]=low[u]=++tot;
  61. s.push(u);
  62. for(int i=last[u];i;i=g[i].next)
  63. {
  64. int v=g[i].to;
  65. if(!dfn[v])
  66. {
  67. tarjan(v);
  68. low[u]=min(low[u],low[v]);
  69. }
  70. else if(!co[v])
  71. {
  72. low[u]=min(low[u],dfn[v]);
  73. }
  74. }
  75. if(low[u]==dfn[u])
  76. {
  77. col++;cnt=;
  78. for(;;)
  79. {
  80. int x=s.top();s.pop();
  81. co[x]=col;
  82. cnt++;
  83. if(cnt>) pd=;//如果一个强联通分量中存在不止一个点,说明有环
  84. if(x==u) break;
  85. }
  86. }
  87. }
  88.  
  89. int main()
  90. {
  91. scanf("%d%d",&n,&m);
  92. for(int i=;i<=m;i++)
  93. {
  94. scanf("%s",aa);
  95. add(aa[]-'A'+,aa[]-'A'+);
  96. if(aa[]-'A'+==aa[]-'A'+)
  97. {
  98. printf("Inconsistency found after %d relations.",i);//这里需要特判一下,不然第一个点会wa
  99. return ;
  100. }
  101. de[aa[]-'A'+]++;
  102. de1[aa[]-'A'+]=de[aa[]-'A'+];
  103. for(int j=;j<=n;j++)
  104. de1[j]=de[j];
  105. tot=;col=;cc=;pd1=;
  106. memset(co,,sizeof(co));
  107. memset(dfn,,sizeof(dfn));
  108. memset(low,,sizeof(low));
  109. while(s.size()) s.pop();
  110. while(ss.size()) ss.pop();
  111. for(int j=;j<=n;j++)
  112. {
  113. if(!dfn[j])
  114. {
  115. tarjan(j);//tarjan判环
  116. }
  117. }
  118. if(pd==)
  119. {
  120. printf("Inconsistency found after %d relations.",i);
  121. return ;
  122. }
  123. topo();//topo检查topo序是否唯一
  124. if(pd1==)
  125. {
  126. printf("Sorted sequence determined after %d relations: ",i);
  127. for(int j=;j<=n;j++)
  128. {
  129. printf("%c",bb[j]);
  130. }
  131. printf(".");
  132. return ;
  133. }
  134. }
  135. printf("Sorted sequence cannot be determined.");
  136. return ;
  137. }

P1347 排序的更多相关文章

  1. 洛谷——P1347 排序

    洛谷—— P1347 排序 题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们 ...

  2. P1347 排序 (拓扑排序,tarjan)

    题目 P1347 排序 解析 打开一看拓扑排序,要判环. 三种情况 有环(存在矛盾) 没环但在拓扑排序时存在有两个及以上的点入度为0(关系无法确定) 除了上两种情况(关系可确定) 本来懒了一下,直接在 ...

  3. 洛谷 P1347 排序

    题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们将给你一系列形如A<B ...

  4. luogu P1347 排序

    题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们将给你一系列形如A<B ...

  5. 洛谷P1347 排序

    这个题看到很多人写Topo排序,其实这道题第一眼看更像是一个差分约束的裸题QWQ... 令dis[x]表示x的相对大小(1是最小,n是最大),显然,对于一个关系A<B,我们有dis[A]< ...

  6. POJ1094 Sorting It All Out LUOGU 排序

        Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 40012   Accepted ...

  7. 23-25 October in 614

    Practice sort 给定一系列形如 \(A<B\) 的不等关系,判断前 \(k\) 个不等关系是否即可确定 \(n\) 个元素之间的大小顺序:如果不可确定,判断前 \(k\) 个不等关系 ...

  8. 【洛谷P1347】排序

    题目大意:给定 N 个变量和 M 个变量之间的偏序关系,问能否求出这 N 个变量之间的一个全序.若能,输出最少利用多少条已知信息即可求的结果,且输出该全序:若无解,输出到第几条已知信息可以判定无解:若 ...

  9. 题解【洛谷P1347】排序

    题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列\(A,B,C,D\) 表示\(A<B,B<C,C<D\).在这道题中,我们将给你一系列 ...

随机推荐

  1. python模拟登陆Github示例

    首先进入github登录页:https://github.com/login 输入账号密码,打开开发者工具,在Network页勾选上Preserve Log(显示持续日志),点击登录,查看Sessio ...

  2. springboot实现简单的文件上传

    承接上一篇,这里记录一下简单的springboot文件上传的方式 首先,springboot简单文件上传不需要添加额外的jar包和配置 这里贴一下后端controller层的实现代码 补一份前台的HT ...

  3. spring 方法验证参数

    1:实体使用 @Valid    使用 validation  类注解 2:String 使用 controller 添加 @Validated @NotBlank(message = "i ...

  4. [2019.04.16] 由Python写成的自动解压脚本

    很久很久以前(二十七天吧……大概)被要求写一个脚本来检索并解压磁盘上所有的以特定格式命名的tar文件,于是乎学习和摸鱼就一起开始了. 这次要写的脚本,针对的是这样的文件结构: 文件结构如上图所示 可以 ...

  5. 如何规避“Flash中国特供版”

    如何规避“Flash中国特供版” 来源  http://blog.sina.com.cn/s/blog_4e1bc3e90102xn0k.html 浏览国内网站,尤其是一些很重要或者很常用,但是很落后 ...

  6. 百度地图--JS版

    百度地图JS版本 ----选择关键字地图展示对应地址---- CSS body, html { width: %; height: %; margin: ; font-family: "微软 ...

  7. (十四)QFile操作,QByteArray,文件流操作,QTextStream,QDataStream,QFileInfo, QIODevice

    QFile f 1.readall #include "widget.h" #include "ui_widget.h" #include <QFileD ...

  8. 运行adb命令报错adb server version (31) doesn't match this client (39); killing...

    执行adb devices 报错 原因分析: 这个是socket 的端口被占用了,我这里是因为360手机助手占用了这个端口,所以其他的就不能够用了. 解决办法: 卸载了360的手机助手就可以了 首先 ...

  9. 数组的处理方法,filter的用法

    在数组的使用中,我们通常会有数组的过滤的需求,比如值 在某个范围内的数字,用来组成一个新的数组,这就用到了数组的过滤 例: var number=[23,3,51,65,13,45,65,23,63] ...

  10. 微信小程序授权登录

    目录 自定义授权页面 点击授权登录后出现微信自带的授权登录弹窗 <!--index.wxml--> <!-- 授权界面 --> <cover-view class='au ...