[ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)
Description
Input
Output
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
解题思路: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算法 判断关系是否矛盾或统一)的更多相关文章
- ACM: poj 1094 Sorting It All Out - 拓扑排序
poj 1094 Sorting It All Out Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%lld & ...
- poj 1094 Sorting It All Out (拓扑排序)
http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- POJ 1094 Sorting It All Out 拓扑排序 难度:0
http://poj.org/problem?id=1094 #include <cstdio> #include <cstring> #include <vector& ...
- 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 ...
- poj 1094 Sorting It All Out_拓扑排序
题意:是否唯一确定顺序,根据情况输出 #include <iostream> #include<cstdio> #include<cstring> #include ...
- PKU 1094 Sorting It All Out(拓扑排序)
题目大意:就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列. 是典型的拓扑排序,但输出格式上确有三种形式: 1.该字母序列有序,并依次输出: 2.判断该序列是否唯一: 3.该序列字母次序之间 ...
- poj 1094 Sorting It All Out(图论)
http://poj.org/problem?id=1094 这一题,看了个大牛的解题报告,思路变得非常的清晰: 1,先利用floyd_warshall算法求出图的传递闭包 2,再判断是不是存在唯一的 ...
- poj 1094 Sorting It All Out 解题报告
题目链接:http://poj.org/problem?id=1094 题目意思:给出 n 个待排序的字母 和 m 种关系,问需要读到第 几 行可以确定这些字母的排列顺序或者有矛盾的地方,又或者虽然具 ...
- POJ 1094 Sorting It All Out【拓扑排序】
题目链接: http://poj.org/problem?id=1094 题意: 给定前n个字母的大小关系,问你是否 根据前xxx个关系得到上升序列 所有关系都无法确定唯一的一个序列 第xxx个关系导 ...
随机推荐
- Linux内核分析第二周学习总结:操作系统是如何工作的?
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 ...
- 实践一:Linux基础实践
一.Linux基础实践 1.1 1. 掌握软件源的维护方法,配置系统使用软件源镜像.掌握通过软件源来查找,安装,卸载,更新软件的方法. 这部分内容在许多学长学姐的报告里都有很详细的讲解,我在此就不赘述 ...
- ubuntu初次安装后设置root用户密码
在ubuntu系统下,为了安全起见,在安装过程中,系统屏蔽了用户设置root用户. 设置方法如下: 登录普通用户 打开终端 sudo passwd[sudo] password for [userna ...
- 济南学习D2T2__数学分析题
[问题描述]有N个数,随机选择一段区间,如果这段区间的所有数的平均值在[l,r]中则你比较厉害.求你比较厉害的概率.[输入格式]第一行有三个数N,l,r,含义如上描述.接下来一行有N个数代表每一个数的 ...
- Particle Playground 3.03 - 粒子特效王者
<ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op ...
- IOS网络编程。。
ASI 与AFN框架: 越低层性能越好. AFNetworking ASIHTTPRequest(性能好点) NSURL会更好. NSURL NSURLRequest NSData * data = ...
- Hibernate之创建命名策略
在开发软件时,通常会要求每个开发人员遵守共同的命名策略.例如,数据库的表名及字段名的所有字符都要大写,表名以“S”结尾.对于Customer类,对应的数据库表名为CUSTOMERS.为了在映射文件中遵 ...
- iOS获取通讯录 电话号码与姓名
// 还是导入 #import <AddressBook/AddressBook.h> - (void)fetchAddressBookBeforeIOS9{ ABAddressBookR ...
- Java script基础 回顾
一.语法 代码与C#相似,变量使用的是var引用出来,包含所有类型:可以直接使用,不用定义. 也是有内置分类的.例如:var b="10" var c=10;一个是字符串一个是整 ...
- 如何获取eID——公安部发行的网络实名认证方式
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...