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 ...
随机推荐
- windows查看服务端口
开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务管理器中没有PID这一项,可以在任务管理器中选&qu ...
- [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.2.1
For fixed basis of in $\scrH$ and $\scrK$, the matrix $A^*$ is the conjugate transpose of the matrix ...
- How to change the property of a control from a flowlayoutpanel?
Well, the easiest way would be to retain an explicit reference to the buttons you're adding. Otherwi ...
- c++ 11 key note
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- classLoader (一)
不说废话,上代码吧. 随便写一个类,他是由appclassLoader加载的 package classLoaderExample; class Bean { public void test() { ...
- 华为2015 简单 字典输入法 java
题目摘自http://blog.csdn.net/dongyi91/article/details/38639915 写了2个小时,水平太菜了 入法的编码原理为:根据已有编码表,当输入拼音和数字后输出 ...
- 以后坚持用java
1.不要贪多,现在专心学习java.读一些jvm的书. 2.研究lucene,hadoop.mahout,和日后用的自然语言分析lingpipe. 3.对于数据挖掘方向,专注与weka的学习,同时注意 ...
- oracle 分区表和分区索引
很复杂的样子,自己都没有看完,以备后用 http://hi.baidu.com/jsshm/item/cbfed8491d3863ee1e19bc3e ORACLE分区表.分区索引ORACLE对于分区 ...
- 利用JDBC连接Eclipse和mySQL5.1.26数据库
初学JDBC,看了看书,自己动手的时候还是有很多地方有问题,最终终于解决了实现了数据库的连接.现将整个步骤描述如下: 环境:mySQL5.1.26(win 32bit), Eclipse JavaEE ...
- 【Java基础】List迭代并修改时出现的ConcurrentModificationException问题
现在有一个需求,要遍历一个List,假设List里面存储的是String对象,然后该需求事判断里面如果有某个对象,则添加一个新的对象进去.自然,我们得出下面的代码: import java.util. ...