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

 
题目大意:给你一些大写字母间的大小排序关系,判断以下3中情况:1 能唯一确定它们的排列顺序,2 所给关系是矛盾的,3 到最后也不能确定它们之间的关系。

解题思路:a、出现矛盾也就是在比较大小关系的过程中出现环,可以通过Floyd算法由邻接矩阵求出可达矩阵,再判断是否存在map[i][i]=1的情况

b、如果没有环且每个点的出度+入度==n-1,则表明字母之间两两关系确定,构成唯一的一个序列,存在答案,否则不存在。

c、当答案存在时,利用拓扑排序确定各点顺序。

相关知识:a、Floyd算法:Floyd-Warshall算法,简称Floyd算法,用于求解任意两点间的最短距离,时间复杂度为O(n^3)。其一般形式为:

 void Floyd(){
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(dist[i][k]+dist[k][j]<dist[i][j])
dist[i][j]=dist[i][k]+dist[k][j];
}

在调用它之前只需做一些简单的初始化:dist[i][i]=0,其他dist为INF。注意这里存在一个潜在问题:当INF定义太大,加法dist[i][k]+dist[k][j]可能会溢出!但如果INF太小,可能会是长度为INF的边真的变成最短路的一部分。因此INF不能太大也不能太小,要先估算一下!如果坚持认为不应该允许INF和其他值相加,就需要把代码改成:

 void Floyd(){
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(dist[i][k]<INF && dist[k][j]<INF && dist[i][k]+dist[k][j]<dist[i][j])
dist[i][j]=dist[i][k]+dist[k][j];
}

此外本题用到了有向图的传递闭包:在有向图中,有时不必关心路径的长度,而只关心两点是否有通路,则可以用1、0分别表示“连通”和“不连通”。这样除了预处理需要做少许修改外,主算法只需:

 void Floyd(){
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(dist[i][k] && dist[k][j])
dist[i][j]=;
}

b、拓扑排序:拓扑排序是对有向无环图(DAG图)的一种排序。表示了顶点按边的方向出现的先后顺序。如果有环,则无法表示两个顶点的先后顺序。

在现实生活中,也会有不少应用例子,比如学校课程布置图,要先修完一些基础课,才可以继续修专业课。

有向图可以拓扑排序的条件是:图中没有环。

                   具体方法:
                   ⑴ 从图中选择一个入度为0的点加入拓扑序列。
                   ⑵ 从图中删除该结点以及它的所有出边(即与之相邻点入度减1)。

反复执行这两个步骤,直到所有结点都已经进入拓扑序列。

相关链接:Folyd算法详解 http://www.cppblog.com/wing/archive/2011/03/10/141511.html

      如何理解拓扑排序算法 http://www.cnblogs.com/shanyou/archive/2006/11/16/562861.html

      拓扑排序-离散数学-详解 http://sjjg.js.zwu.edu.cn/SFXX/tu/tu5.6.1.html

AC代码

 #include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<stack>
using namespace std; #define maxn 30
int n,m;
bool map[maxn][maxn],visit[maxn];
int indegree[maxn],outdegree[maxn];
char str[maxn],ch[maxn]; bool Floyd(){
for(int i=;i<n;i++)//Floyd对邻接矩阵的运算求可达矩阵
for(int j=;j<n;j++)
for(int k=;k<n;k++)
if(map[j][i] && map[i][k])
map[j][k]=;
for(int l=;l<n;l++)//判断是否成环
if(map[l][l])
return ;
return ;
}//Floyd算法对0-1邻接矩阵判断是否有环:map[i][i]=1 bool only_sure(){
memset(indegree,,sizeof(indegree));
memset(outdegree,,sizeof(outdegree));
for(int i=;i<n;i++)//计算出度和入度
for(int j=;j<n;j++)
if(map[i][j])
indegree[j]++,outdegree[i]++;
for(int k=;k<n;k++)//所有点出度入度之和均为n-1则说明所有关系确定
if(indegree[k]+outdegree[k]!=n-)
return ;
return ;
} //拓扑排序:从图中选择一个入度为0的点加入拓扑序列
// 从图中删除该结点以及它的所有出边(即与之相邻点入度减1)
void toplogical_sort(){
stack<int> Q;
int id=;
for(int i=;i<n;i++)
if(indegree[i]==){
Q.push(i);
break;
}
memset(visit,,sizeof(visit));
while(!Q.empty()){
int cur=Q.top();Q.pop();
visit[cur]=true;
str[id++]=cur+'A';
for(int j=;j<n;j++){
if(!visit[j] && map[cur][j])indegree[j]--;//将所有子节点的入度-1
if(!visit[j] && indegree[j]==)Q.push(j);
}
}
str[id]='\0';
} int main(){
while(cin>>n>>m){
if(n== && m==)break;
memset(map,,sizeof(map));
int flag1=;//标记矛盾出现时的步数
int flag2=;//标记关系确认时的步数
for(int i=;i<=m;i++){//边输入边检测
cin>>ch;
map[ch[]-'A'][ch[]-'A']=;
if(flag1 ||flag2)continue;
else if(!Floyd())flag1=i;
else if(only_sure()){
toplogical_sort ();
flag2=i;
}
}
if (flag1) printf("Inconsistency found after %d relations.\n",flag1);
else if (flag2) printf("Sorted sequence determined after %d relations: %s.\n",flag2,str);
else printf("Sorted sequence cannot be determined.\n");
}return ;
}

[ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)的更多相关文章

  1. ACM: poj 1094 Sorting It All Out - 拓扑排序

    poj 1094 Sorting It All Out Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & ...

  2. poj 1094 Sorting It All Out (拓扑排序)

    http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  3. POJ 1094 Sorting It All Out 拓扑排序 难度:0

    http://poj.org/problem?id=1094 #include <cstdio> #include <cstring> #include <vector& ...

  4. POJ 1094 Sorting It All Out (拓扑排序) - from lanshui_Yang

    Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...

  5. poj 1094 Sorting It All Out_拓扑排序

    题意:是否唯一确定顺序,根据情况输出 #include <iostream> #include<cstdio> #include<cstring> #include ...

  6. PKU 1094 Sorting It All Out(拓扑排序)

    题目大意:就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列. 是典型的拓扑排序,但输出格式上确有三种形式: 1.该字母序列有序,并依次输出: 2.判断该序列是否唯一: 3.该序列字母次序之间 ...

  7. poj 1094 Sorting It All Out(图论)

    http://poj.org/problem?id=1094 这一题,看了个大牛的解题报告,思路变得非常的清晰: 1,先利用floyd_warshall算法求出图的传递闭包 2,再判断是不是存在唯一的 ...

  8. poj 1094 Sorting It All Out 解题报告

    题目链接:http://poj.org/problem?id=1094 题目意思:给出 n 个待排序的字母 和 m 种关系,问需要读到第 几 行可以确定这些字母的排列顺序或者有矛盾的地方,又或者虽然具 ...

  9. POJ 1094 Sorting It All Out【拓扑排序】

    题目链接: http://poj.org/problem?id=1094 题意: 给定前n个字母的大小关系,问你是否 根据前xxx个关系得到上升序列 所有关系都无法确定唯一的一个序列 第xxx个关系导 ...

随机推荐

  1. 【原】JS正则表达式里的控制符

    正则表达式易于使用而又让人费解,乍一看上去,就像是一行行的乱码,但是它的功能确实又不容小觑.今天整理正则时,纠正了自己的一个误解. 先缕一缕: 正则表达式的两种声明方式: 字面量.构造器 (RegEx ...

  2. 安装BeautifulSoup

    [安装BeautifulSoup] $ pip install beautifulsoup4 参考:https://www.crummy.com/software/BeautifulSoup/bs4/ ...

  3. __future__

    [__future__] __future__用于改变python特性. 参考:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb4 ...

  4. 使用JdbcTemplate简化JDBC操作 实现数据库操作

    使用Spring JDBC框架方遍简单的完成JDBC操作,满足性能的需求且灵活性高. Spring JDBC框架由4个部分组成,即core.datasource.object.support. org ...

  5. Bridge(桥接)-对象结构型模式

    1.意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 2.动机 在抽象类与它的实现之间起到桥梁作用,使它们可以独立地变化. 3.适用性 不希望在抽象和它的实现部分之间有一个固定的绑定关系. ...

  6. rm: Argument list too long

    rm -rf  /testdir/* -bash: /bin/rm: Argument list too long 解决: cd /testdir/; ls | xargs rm -rf

  7. 让图片在div 中居中的方法

    方法一: 思路:利用text-align属性将图片水平居中,然后设置padding-top的值使其垂直居中. 结构如下: <div> <img src="images/tt ...

  8. MongoDB数据库简介及安装

    一.MongoDB数据库简介 简介 MongoDB是一个高性能,开源,无模式的,基于分布式文件存储的文档型数据库,由C++语言编写,其名称来源取自"humongous",是一种开源 ...

  9. 【erlang】IPv6格式转IPv4

    erlang里面的httpd模块保存的http请求头里面,其中remote_addr 保存的是IPv6的格式. 即使是IPv4,也会用IPv6的格式来保存.如 {remote_addr, " ...

  10. rocksdb编译测试的正确姿势

    需要先安装 gflags 在进行 make db_bench 不然运行 db_bench 会出现 Please install gflags to run rocksdb tools 错误 bench ...