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:

4 6
A<B
A<C
B<C
C<D
B<D
A<B
输出样例#1:

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

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

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

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

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 排序的更多相关文章

  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. Leetcode 8 Two Pointers

    Two Pointers 1. 28. Implement strStr() 用 i 记录haystack偏移量,j 记录 needle 的偏移量. class Solution { public i ...

  2. GIt帮助文档之忽略某些文件——忽略python虚拟环境文件夹(转)

    前言:为避免多个Python项目下安装库之间的冲突,或为轻松打包某个项目,建议在每个项目文件夹下安装Python虚拟环境,并在虚拟环境内进行操作,之后你安装的任何库和执行的任何程序都是在这个环境下运行 ...

  3. nodejs 搭建本地静态服务器

    1. http-server 参看 https://www.npmjs.com/package/http-server 使用http-server搭建本地静态服务器 全局安装http-server n ...

  4. BZOJ1112[POI2008]砖块Klo——非旋转treap

    题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...

  5. How To Configure NetScaler AppFlow for SolarWinds

    How To Configure NetScaler AppFlow for SolarWinds 来源  https://support.citrix.com/article/CTX227300 A ...

  6. Matlab 中subsystem mask封装子系统

    Icon&port %%外型图表封装 %%.曲线型标注: plot(cos(:*pi),sin(:*pi)) %%.文字型标注: disp('PID\n控制器') %%.曲线加文字型标注: p ...

  7. MongoDB官网配置项目整理

    MongoDB的配置文件共有10个项目: systemLog:processManagement:net:security:storage:operationProfiling:replication ...

  8. SQL SERVER 查询所有数据表名称和数据行数

    SELECT a.name, b.rows FROM sysobjects AS a INNER JOIN sysindexes AS b ON a.id = b.id WHERE ( a.type ...

  9. CTF--web 攻防世界web题 robots backup

    攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...

  10. web故障排查常用命令

    整理总结了一些常用分析网站的命令方便大家快速定位故障所在排除故障,最小化的减少故障给业务带来的影响. 端口连接类 1.查看TCP连接状态 netstat -nat |awk '{print $6}'| ...