P1347 排序
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个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况)
输入输出样例
4 6
A<B
A<C
B<C
C<D
B<D
A<B
Sorted sequence determined after 4 relations: ABCD.
3 2
A<B
B<A
Inconsistency found after 2 relations.
26 1
A<Z
Sorted sequence cannot be determined
这道题我来提供一种tarjan+拓扑排序的做法,首先我们考虑满足第二种情况的序列,如果存在矛盾,那么这个图中一定存在环,这样我们就可以用tarjan缩点判断一下是否存在环,有一点需要注意,就是如果小于号两边的数相同,那么就一定产生矛盾(非常坑)。对于第一种情况的序列,不难看出这个序列的拓扑序一定是唯一的,而且一定不存在环,也就是说每次拓扑时在栈中的元素一定只有唯一的一个,这样只需在每次拓扑开始时判断一下元素个数即可。如果第一和第二种情况均不满足,那么一定就是第三种情况咯。
最后附上代码:
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<stack>
#define maxn 1005
using namespace std; struct edge
{
int next;
int to;
}g[maxn<<];
int n,m,num,col,tot,cnt,pd,cnt2,cc,pd1;
int last[maxn],de[maxn],dfn[maxn],low[maxn],co[maxn],de1[maxn];
char aa[],bb[maxn];
stack<int>s;
stack<int>ss; void add(int from,int to)
{
g[++num].next=last[from];
g[num].to=to;
last[from]=num;
} void topo()
{
for(int i=;i<=n;i++)
{
if(de1[i]==)
{
ss.push(i);
}
}
while(ss.size())
{
if(ss.size()>)//如果栈中多余一个元素,说明topo序不唯一
{
pd1=;
break;
}
int u=ss.top();ss.pop();
bb[++cc]=char(u+'A'-);
for(int i=last[u];i;i=g[i].next)
{
int v=g[i].to;
de1[v]--;
if(de1[v]==)
{
ss.push(v);
}
}
}
} void tarjan(int u)
{
dfn[u]=low[u]=++tot;
s.push(u);
for(int i=last[u];i;i=g[i].next)
{
int v=g[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!co[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
col++;cnt=;
for(;;)
{
int x=s.top();s.pop();
co[x]=col;
cnt++;
if(cnt>) pd=;//如果一个强联通分量中存在不止一个点,说明有环
if(x==u) break;
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%s",aa);
add(aa[]-'A'+,aa[]-'A'+);
if(aa[]-'A'+==aa[]-'A'+)
{
printf("Inconsistency found after %d relations.",i);//这里需要特判一下,不然第一个点会wa
return ;
}
de[aa[]-'A'+]++;
de1[aa[]-'A'+]=de[aa[]-'A'+];
for(int j=;j<=n;j++)
de1[j]=de[j];
tot=;col=;cc=;pd1=;
memset(co,,sizeof(co));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
while(s.size()) s.pop();
while(ss.size()) ss.pop();
for(int j=;j<=n;j++)
{
if(!dfn[j])
{
tarjan(j);//tarjan判环
}
}
if(pd==)
{
printf("Inconsistency found after %d relations.",i);
return ;
}
topo();//topo检查topo序是否唯一
if(pd1==)
{
printf("Sorted sequence determined after %d relations: ",i);
for(int j=;j<=n;j++)
{
printf("%c",bb[j]);
}
printf(".");
return ;
}
}
printf("Sorted sequence cannot be determined.");
return ;
}
P1347 排序的更多相关文章
- 洛谷——P1347 排序
洛谷—— P1347 排序 题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们 ...
- P1347 排序 (拓扑排序,tarjan)
题目 P1347 排序 解析 打开一看拓扑排序,要判环. 三种情况 有环(存在矛盾) 没环但在拓扑排序时存在有两个及以上的点入度为0(关系无法确定) 除了上两种情况(关系可确定) 本来懒了一下,直接在 ...
- 洛谷 P1347 排序
题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们将给你一系列形如A<B ...
- luogu P1347 排序
题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们将给你一系列形如A<B ...
- 洛谷P1347 排序
这个题看到很多人写Topo排序,其实这道题第一眼看更像是一个差分约束的裸题QWQ... 令dis[x]表示x的相对大小(1是最小,n是最大),显然,对于一个关系A<B,我们有dis[A]< ...
- POJ1094 Sorting It All Out LUOGU 排序
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 40012 Accepted ...
- 23-25 October in 614
Practice sort 给定一系列形如 \(A<B\) 的不等关系,判断前 \(k\) 个不等关系是否即可确定 \(n\) 个元素之间的大小顺序:如果不可确定,判断前 \(k\) 个不等关系 ...
- 【洛谷P1347】排序
题目大意:给定 N 个变量和 M 个变量之间的偏序关系,问能否求出这 N 个变量之间的一个全序.若能,输出最少利用多少条已知信息即可求的结果,且输出该全序:若无解,输出到第几条已知信息可以判定无解:若 ...
- 题解【洛谷P1347】排序
题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列\(A,B,C,D\) 表示\(A<B,B<C,C<D\).在这道题中,我们将给你一系列 ...
随机推荐
- ElementUI DatePicker 日期选择器控制选择时间范围
选择今天以及今天之后的日期 <el-date-picker v-model="value1" type="date" placeholder=" ...
- 单元测试之Fixture
声明: 作者:zhaojun 创建日期:2017-08-04 更新日期:2017-08-07 一.什么是Fixture,Fixture有什么作用,为什么需要使用Fixture # 下载 pip i ...
- Ubuntu 16.04 RabbitMq 安装与运行(安装篇)
Ubuntu 16.04 RabbitMq 安装与运行(安装篇) 2018年08月15日 15:05:24 我跟吴彦祖四六开 阅读数:1966 前言 目前公司用阿里云 + redis 的方式实现的 ...
- 「Algospot」龙曲线DRAGON
一道考验思维的好题,顺便总结求第k大问题的常规思路: 传送门:$>here<$ 题意 给出初始串FX,每分形一次所有X替换为X+YF,所有Y替换为FX-Y.问$n$代字符串第$p$位起长度 ...
- KEIL之工程单独文件属性修改
@2019-04-29 [小记] 可以设置文件是否参与编译.内存分配.宏定义等属性设置
- git学习02 - log查看&版本回退
1.查看更新记录 git log / git log --pretty=oneline D:\learn\git_test>git log commit a915e7b12076673d778 ...
- [BJOI2017]树的难题
题目描述 给你一棵 n 个点的无根树. 树上的每条边具有颜色.一共有 m 种颜色,编号为 1 到 m.第 i 种颜色的权值为 ci. 对于一条树上的简单路径,路径上经过的所有边按顺序组成一个颜色序列, ...
- LOJ#2244 起床困难综合症
解:m = 0的部分分,直接模拟.有and 0的部分分,直接模拟.<=1000的部分分,枚举攻击力之后模拟.所有操作相同的部分分,可以合并成只有一个操作.然后枚举m或者逐位贪心. 正解是逐位贪心 ...
- JavaScript千分符---正则实现
一般在JavaScript中实现千分符,是使用切割+连接一顿操作 这里尝试一下使用正则快速实现千分符 let num0 = '12' let num1 = '123' let num2 = '1234 ...
- Python的开发之路
一.python入门 二.基本数据类型 三.输入与输出 四.基本运算符 五 .流程控制之if判断 六.流程控制之while循环 七.流程控制之for循环 八.数据类型与内置方法 九.文件的处理 十.字 ...