比较模板的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. leveldb源码分析--Comparator

    既然leveldb是一个按Key序组织的LSM-Tree实现,那么对于Key的比较就是非常之重要了,这个Key的比较在leveldb中是Comparator的形式出现的.我们首先来看看Comparat ...

  2. NodeJS链接MySql数据库

    //1.用npm命令安装mysql模块 npm install mysql //2.js文件中引入mysql模块 const mysqlModule = require('mysql'); //3.创 ...

  3. 【爬坑】在 IDEA 中运行 Hadoop 程序 报 winutils.exe 不存在错误解决方案

    0. 问题说明 环境为 Windows 10 在 IDEA 中运行 Hadoop 程序报   winutils.exe 不存在  错误 1. 解决方案 [1.1 解压] 解压 hadoop-2.7.3 ...

  4. MySQL索引原理以及类型

    1.什么是索引 索引是在MySQL的存储引擎上,对其表中的某个列或多列通过一些算法实现可快速查询出结果的一种方法. 2.为什么要有索引 就像一本书要有目录一样,我们可快速通过目录来查找对应的章节得出结 ...

  5. XtraEditors六、ListBoxControl、CheckedListBoxControl、ImageListBoxControl

    ListBoxControl 效果如下: 示例代码: string[] girlArr = { "面码", "Saber", "Mathilda&qu ...

  6. 百度地图Key的设置方法

    一.为什么要设置百度Key 万能地图下载器提供了百度POI的下载功能,但由于本软件用户群极大,会导致一天之内访问量超出300万次以上而无法继续下载. 因此,当POI下载不成功能,用户可以自己申请百度地 ...

  7. Rx = Observables(响应) + LINQ(声明式语言) + Schedulers(异步)

    Reactive = Observables(响应)+ Schedulers(异步). Extensions = LINQ(语言集成查询) LINQ: The Operators of Reactiv ...

  8. 协程运行原理猜测: async/await

    1.根据await调用链寻找最终的生产者或服务提供者: 2.请求服务: 3.进行执行环境切换,跳出顶层函数(第一个无await修饰的函数),执行后面的语句: 4.服务完成,将服务数据复制给最底层的aw ...

  9. php header函数导出excel表格

    推荐一个除了用PHPExcel导出表格之外的另外一种比较简单不需要引入类文件的表格导入方法——header()导出excel表格. 导出表格的步骤封装成了方法,以便于重复使用,代码如下: /** * ...

  10. JAVA springmvc 转换器

    一.有时候springmvc给咱们提供的数据转换并不能转换所有类型比如说由字符串类型转换Date类型,这时候需要我们自定义转换器,帮助springmvc转换我们需要的类型. 二.1)定义我们的转换器: ...