nyoj349 poj1094 Sorting It All Out(拓扑排序)
nyoj349 http://acm.nyist.net/JudgeOnline/problem.php?pid=349
poj1094 http://poj.org/problem?id=1094
这两个题是一样的,不过在poj上A了才算真的过,ny上数据有一点弱。
题目大意输入n,m。 一共有n个字母(从A开始), m行语句每个语句“x﹤y”,说明x,y之间的偏序关系。让你判断是否可以通过这些关系得到一个唯一的升序序列,若能则输出这个序列并指出通过前多少条语句得出的,如果n个字母间存在矛盾,输出相应语句并指出那条语句开始出现矛盾的。如果没有唯一序列又不存在矛盾就输出想应信息。
分析:
所用算法拓扑排序:使有向图G的每一条边(u,v)对应的u都排在v的前面。不难发现如果图中存在又向环,则不存在拓扑排序。拓扑排序答案可能有多个(例如:a﹤b; c﹤b; d﹤c; 排序可为adcb或dacb),但此题中要求排序唯一。
首先我们可以把每组小于关系看成是一个又向边,这样我们还会得到一个又向图,我们所要做的就是把图中所有点排序,因为需要知道在哪出现矛盾,在哪可以得到唯一排序的,那么我们就每输入一个边(小于关系)就更新一次图,做一回拓扑排序,看是否能得到唯一排序、有矛盾。如果所有边都结束了还没有矛盾,那就看看排序是否唯一。
在排序的时候我们需要记录每个点u所排的位置(小的排在前面),已知的由u为出发点的边可能有多个(也就是已给出多个“u﹤xi”的偏序关系),那么u点所拍的位置就是所有xi中的最小值-1。
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
//v[i]标记第i个字母是否dfs过, sum[i]存储排在第i位的字母有几个(用来判断排序是否唯一)
int n, m, v[], a[], sum[], k[];
vector<int> vec[];
struct egde
{
int x, y;
}e[];
int dfs(int x)
{
int flag = ;
v[x] = -;//正在搜索的点标记为-1
int mi = n+;
for(int i = ; i < vec[x].size(); i++)
{
flag = ;
int y = vec[x][i];
if(v[y] < ) return ;
else if(v[y] == )
{
if(dfs(y) == )
return ;
else
mi = min(mi, a[y]);
}
mi = min(mi, a[y]);
}
v[x] = ;//搜索过的点标记为1
//a[x]记录字母x排在第几位
if(flag == )//flag=1说明有已知比他大的点, x就排在 所有比它大的点的最小位置 的前面
a[x] = mi - ;
else a[x] = n;//flag= 0,说明x是已知最大的点之一,排在最后一位n位
return ;
}
int topu()
{
memset(v, , sizeof(v));
for(int i = ; i <= n; i++) a[i] = n+;//初始化所有点的排序位置为n+2;
for(int i = ; i <= n; i++)
{
if(v[i] == && vec[i].size() != )
{
int tem = dfs(i);
if(tem == ) return ;
}
}
return ;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF && n && m)
{
for(int i = ; i <= m; i++)
{
char a, b, c;
int tem;
cin >> a >> c >> b;
tem = a - 'A' + ; e[i].x = tem;//e[i]存储第i条边的两个点
tem = b - 'A' + ; e[i].y = tem;
}
int error = -;
int flag;//标记排序是否为为一
for(int i = ; i <= n; i++) {vec[i].clear();}
for(int i = ; i <= m; i++)
{
flag = ;
vec[e[i].x].push_back(e[i].y);//不断加入边, 每次加边都跟新存出边的vec;
error = topu();//每次加边都进行一次拓扑排序, 返回值=0时,存在矛盾, 返回值=1时没有矛盾
if(error == )//error = 0, 则有矛盾
{
printf("Inconsistency found after %d relations.\n", i);
break;
}
else if(error == )
{
memset(sum, , sizeof(sum));
flag = ;
for(int i = ; i <= n; i++)
{
if(a[i] == n + )//当字母i排在第n+2位时,说明字母i没由与它连接的边,
{
flag = ;continue;
}
sum[a[i]]++;//sum[i]存储排在第i位的字母有几个(用来判断排序是否唯一)
k[a[i]] = i;//k[i]记录排在第i位的字母
if(sum[a[i]] > ){flag = ; break;}//如果排在同一位置的字母不止一个,则有矛盾
}
if(flag == )//若所有点都有与之连接的边,并且字母所拍的位置不重复则说明排序唯一
{
printf("Sorted sequence determined after %d relations: ", i);
for(int i = ; i <= n; i++)
printf("%c", k[i] + 'A' - );
printf(".\n");
break;
}
}
}
if(flag == )//若不存在矛盾, 但是字母的所排位置有重复,则说明排序不唯一
printf("Sorted sequence cannot be determined.\n");
}
return ;
}
nyoj349 poj1094 Sorting It All Out(拓扑排序)的更多相关文章
- [poj1094]Sorting It All Out_拓扑排序
Sorting It All Out poj-1094 题目大意:给出一些字符串之间的大小关系,问能否得到一个唯一的字符串序列,满足权值随下标递增. 注释:最多26个字母,均为大写. 想法:显然,很容 ...
- POJ1094 Sorting It All Out —— 拓扑排序
题目链接:http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Tot ...
- 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---拓扑排序是否唯一的判断
题目链接: https://vjudge.net/problem/POJ-1094 题目大意: 该题题意明确,就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列.是典型的拓扑排序,但输出格式上 ...
- POJ1094 Sorting It All Out LUOGU 排序
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 40012 Accepted ...
- POJ 1094:Sorting It All Out拓扑排序之我在这里挖了一个大大的坑
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 29984 Accepted: 10 ...
- [ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)
Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...
- 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 ...
随机推荐
- mysql 查看死锁和去除死锁
1.查询是否锁表show OPEN TABLES where In_use > 0; 2.查询进程 show processlist 3. 查询到相对应的进程,然后 kill id 验证(ki ...
- spring--JDBC的支持--7
7.1 概述 7.1.1 JDBC回顾 传统应用程序开发中,进行JDBC编程是相当痛苦的,如下所示: java代码: 以上代码片段具有冗长.重复.容易忘记某一步骤从而导致出错.显示控制事务.显示处 ...
- 运算符优先级 (Transact-SQL)
当一个复杂的表达式有多个运算符时,运算符优先级决定执行运算的先后次序. 执行的顺序可能严重地影响所得到的值. 运算符的优先级别如下表中所示. 在较低级别的运算符之前先对较高级别的运算符进行求值.
- Scala学习笔记(一)数据类型
.类型参数化数组 val arrayString = Array[String](2); arrayString (0)="Hello"; arrayString (1)=&quo ...
- uva_12535 - Probability Through Experiments
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 局域网yum服务器创建
yum createrepo createrepo dir 配置httpd发布yum-repo; 在客户端添加yum.rep配置文件;
- HTML 网页游戏 2048
新手只会一点html和css,javascript基本不会,更别提jQuery了= = 跟着慕课网的教学视频(视频地址:http://www.imooc.com/learn/76)一点点做的,由于自己 ...
- java 日志技术汇总(log4j , Commons-logging,.....)
前言 在Tomcat 与weblogic 中的 日志(log4j) 配置系列一 在系列一 中, 有一个问题一直没有解决,就是部署到weblogic 中应用程序如何通过log4j写日志到文件中? 这里仅 ...
- js http 请求 多个相同参数名传值
最近在用js和api做对接的时候需要传参数类似于 rights=a1&rights=a2 因为有相同的参数名,试过很多方法都被覆盖了. 最后终于发现可以通过rights=[a1,a2]的方式, ...
- 百亿级别数据量,又需要秒级响应的案例,需要什么系统支持呢?下面介绍下大数据实时分析工具Yonghong Z-Suite
Yonghong Z-Suite 除了提供优秀的前端BI工具之外,Yonghong Z-Suite让用户可以选购分布式数据集市来支持实时大数据分析. 对于这种百亿级的大数据案例,Yonghong Z- ...