[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个关系导 ...
随机推荐
- 循序渐进之Spring AOP(6) - 使用@Aspect注解
前面几节的示例看起来让人沮丧,要记忆如此多的接口.类和继承关系,做各种复杂的配置.好在这些只是一种相对过时的实现方式,现在只需要使用@Aspect注解及表达式就可以轻松的使用POJO来定义切面,设计精 ...
- arcgis desktop按ctrl键后地图乱移的解决办法
习惯使用快捷键的,经常会按下ctrl. 但在arcmap中,按下ctrl后,地图乱移.分析发现变为鼠标导航状态,也就是鼠标偏离地图中心,地图就会往鼠标所在方向移动. 解决办法:1. 以前按下esc键, ...
- Java设计模式——适配器模式
JAVA 设计模式 适配器模式 用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器 ...
- linux-curl restful接口测试结果格式化
最近在做restful api, 因为服务器不能直接访问, 所以测试只能通过ScureCRT 在一台linux 上curl. 但是返回结果很多的时候, 发现:草, 这个数据怎么都是乱码? 一大堆数据, ...
- 自定义底部tab
public class MainActivity extends TabActivity implements OnCheckedChangeListener { private RadioGrou ...
- jquery.fileupload插件的简易使用日志
来源:http://yixiandave.iteye.com/blog/1897330 本文内容主要包含fileupload插件传递参数和取回服务器返回数据的方法 jquery.fileupload官 ...
- fastJson顺序遍历JSON字段
fastJson在把json格式的字符串转换成JSONObject的时候,使用的是HashMap,所以排序规则是根据HASH值排序的,如果想要按照字符串顺序遍历JSON属性,需要在转换的时候指定使用L ...
- html制作,点击文字超链接显示文本框,再点击文字超链接隐藏文本框
</head><body> <script> window.onload=function(){ document.getElementById('click'). ...
- java1.7集合源码阅读: Vector
Vector是List接口的另一实现,有非常长的历史了,从jdk1.0开始就有Vector了,先于ArrayList出现,与ArrayList的最大区别是:Vector 是线程安全的,简单浏览一下Ve ...
- java多线程学习-多个线程访问对象共享数据的方式
public class MulitThreadShareData { public static void main(String[] args) { final ShareData1 data1 ...