比较模板的topological-sort题,关键在于每个元素都严格存在唯一的大小关系,而一般的拓扑排序只给出一个可能解,这就需要每趟排序的过程中监视它是不是总坚持一条唯一的路径。

算法导论里面的拓扑排序运用的是DFS the DAG,记录每个顶点的进入时间和离开时间,根据其先后插入单链表的做法。而我认为一种方法是更直观的,就是维护一个入度为0的顶点集合(我用的队列其实没差),每次对其中一个加入结果序列——同时删除它的所有出边——更新其他点的入度的做法,在我的算法数据结构实现模板里有正确实现https://github.com/jily16/ACMCodes(打广告

在判断拓扑排序结果唯一性时这种方法也表现出了一个优势,每次访问0入度集合时查看大小,当元素多于1的时候可行的选择就出现了分歧——即可判定此DAG的拓扑排序不唯一(当然本题的信息在不断更新,所以不能立刻判死)。

AC代码:

 #include <vector>
#include <iostream>
#include <queue>
using namespace std;
//POJ1094
int const INF = 0x3f3f3f3f;
//返回空数组说明暂时不行
//cyclic说明矛盾
vector<int> ts(vector<vector<int> > const &g, bool &cyclic)
{
int n = g.size();
vector<int> d(n);
for (int i = ; i < n; ++i)
{
for (int j = ; j < n; ++j)
{
if (g[i][j] < INF)
{
++d[j];
}
}
}
queue<int> q;
for (int i = ; i < n; ++i) if (d[i] == ) q.push(i);
int d0;
int tot = ;
bool not_unique = false;
vector<int> ans;
while (!q.empty())
{
if (q.size() > )
{
not_unique = true; //解不唯一
}
d0 = q.front();
q.pop();
ans.push_back(d0);
++tot;
for (int i = ; i < n; ++i)
{
if (d[i] != && g[d0][i] < INF)
{
--d[i];
if (d[i] == )
{
q.push(i);
}
}
}
}
if (tot != n) cyclic = true;
if (not_unique) return vector<int>();
else return ans;
}
int main()
{
int n, m;
while (cin >> n >> m && n && m)
{
bool done = false;
vector<vector<int> > g;
char alp1, alp2;
char lessthan;
int num1, num2;
for (int i = ; i < m; ++i)
{
cin >> alp1 >> lessthan >> alp2;
if (done) continue;
num1 = alp1 - 'A';
num2 = alp2 - 'A';
int bignum = max(num1, num2);
//extend the graph
if (g.size() < bignum + )
{
int ori_size = g.size();
for (int i = ; i < ori_size; ++i)
{
for (int j = ; j < bignum + - ori_size; ++j)
{
g[i].push_back(INF);
}
}
for (int i = ; i < bignum + - ori_size; ++i)
{
g.push_back(vector<int>(bignum + , INF));
}
}
g[num1][num2] = ;
//judge from here
bool cycle = false;
if (g.size() < n)
{
ts(g, cycle);
if (cycle)
{
cout << "Inconsistency found after " << i + << " relations.\n";
done = true;
}
else
{
if (i == m - )
{
cout << "Sorted sequence cannot be determined.\n";
done = true;
}
}
}
else
{
vector<int> ans = ts(g, cycle);
if (cycle)
{
cout << "Inconsistency found after " << i + << " relations.\n";
done = true;
}
else
{
if (ans.size() != )
{
cout << "Sorted sequence determined after " << i + << " relations: ";
for (int i = ; i < n; ++i) cout << (char)(ans[i] + 'A');
cout << ".\n";
done = true;
}
else
{
if (i < m - ) continue;
else
{
cout << "Sorted sequence cannot be determined.\n";
done = true;
}
}
}
}
}
}
return ;
}

POJ1094——拓扑排序和它的唯一性的更多相关文章

  1. POJ1094 拓扑排序

    问题:POJ1094   本题考查拓扑排序算法   拓扑排序:   1)找到入度为0的点,加入已排序列表末尾: 2)删除该点,更新入度数组.   循环1)2)直到 1. 所有点都被删除,则找到一个拓扑 ...

  2. poj1094拓扑排序

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

  3. poj1094 拓扑排序(出度入度简单使用)

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

  4. nyoj349 poj1094 Sorting It All Out(拓扑排序)

    nyoj349   http://acm.nyist.net/JudgeOnline/problem.php?pid=349poj1094   http://poj.org/problem?id=10 ...

  5. [poj1094]Sorting It All Out_拓扑排序

    Sorting It All Out poj-1094 题目大意:给出一些字符串之间的大小关系,问能否得到一个唯一的字符串序列,满足权值随下标递增. 注释:最多26个字母,均为大写. 想法:显然,很容 ...

  6. POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)

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

  7. POJ1094 Sorting It All Out —— 拓扑排序

    题目链接:http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Tot ...

  8. POJ1094 字母排序(拓扑排序)

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

  9. 拓扑排序(topsort)

    本文将从以下几个方面介绍拓扑排序: 拓扑排序的定义和前置条件 和离散数学中偏序/全序概念的联系 典型实现算法解的唯一性问题 Kahn算法 基于DFS的算法 实际例子 取材自以下材料: http://e ...

随机推荐

  1. SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交

    假如我们数据库中有两张表Person和Book Person表: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, [CreateTi ...

  2. 4种更快更简单实现Python数据可视化的方法

    数据可视化是数据分析或机器学习项目中十分重要的一环.通常,你需要在项目初期进行探索性的数据分析(EDA),从而对数据有一定的了解,而且创建可视化确实可以使分析的任务更清晰.更容易理解,特别是对于大规模 ...

  3. android kl文件

    android kl(key layout)文件是一个映射文件,是标准linux与anroid的键值映射文件,kl文件可以有很多个,但是它有一个使用优先级: /system/usr/keylayout ...

  4. python基础学习15----异常处理

    异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件). 1.异常的类型 异常的类型多种多样,常见的异常有: AttributeE ...

  5. [Python_2] Python 基础

    0. 说明 Python 基础笔记,使用的版本为 Python 3.6.2 Python 的变量.字符串操作.list.元组.字典.循环.range.类型转换.运算等操作. 1. 引号的使用 字符串使 ...

  6. 乘风破浪:LeetCode真题_036_Valid Sudoku

    乘风破浪:LeetCode真题_036_Valid Sudoku 一.前言 有的时候对于一些基础知识的掌握,对我们是至关重要的,比如ASCII重要字符的表示,比如一些基本类型的长度. 二.Valid ...

  7. Jar版本:java.lang.UnsupportedClassVersionError: ******

    错误原因编译Java和运行Java所使用的Java的版本不一致导致:解决办法修改运行环境的Java版本或者修改编译环境的Java版本,让两者保持一致即可: java.lang.UnsupportedC ...

  8. css3自定义滚动条背景透明

    .editor{ overflow:hidden; height:640px; padding:0 45px; border: 0 none; outline: none; } .editor::-w ...

  9. Android APP的字体设置

    Android系统自带有对字体的设置,这些设置是对字体的显示方式的设置,比如加粗,倾斜,下划线,字号等,但是对于字体本身,比如设置为楷体,隶书等貌似没有.Android系统只有一种默认的,如果需要修改 ...

  10. Node.js实战(七)之交互式解释器

    Node.js REPL(Read Eval Print Loop:交互式解释器) 表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并 ...