ACM/ICPC 之 拓扑排序范例(POJ1094-POJ2585)
两道拓扑排序问题的范例,用拓扑排序解决的实质是一个单向关系问题
POJ1094(ZOJ1060)-Sortng It All Out
题意简单,但需要考虑的地方很多,因此很容易将code写繁琐了,会给力求code精简的强迫症患者一个警醒- -
题意:给出m组逻辑关系式,求n个字母间的排序,分排序成功-排序矛盾-不能确定三种情况输出相应语句
题解:拓扑排序,访问入度为0的结点,邻接点入度-1,然后继续访问入度为0的结点...直到访问完成为止
需要注意的地方在于三种情况根据最早确定的情况来输出,例如先排序完成,但后面的关系式表明排序矛盾,此时按照先排序完成得到的序列输出。
//一道考查拓扑排序的经典例题
//POJ1094-ZOJ1060
//Time:0Ms Memory:188K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std; #define MAX 27 struct Letter {
int in; //入度
int v;
vector<int> p;
}letter[MAX]; int n, m;
char seq[MAX]; int topSort(int total)
{
memset(seq, , sizeof(seq));
int tmp[MAX]; //临时入度数组
for (int i = ; i < n; i++)
tmp[i] = letter[i].in; bool correct = true; //是否可行
for (int i = ; i < total;i++)
{
int cur; //当前字母位置
int cnt = ; //入度为0的个数
for (int i = ; i < n; i++)
if (tmp[i] == )
{
cur = i;
cnt++;
}
if (cnt == ) return -;
if (cnt > ) correct = false; //多选时-不可行但须判断是否矛盾
for (int i = ; i < letter[cur].p.size(); i++)
tmp[letter[cur].p[i]]--;
seq[i] = cur + 'A';
tmp[cur]--;
}
return correct;
} int main()
{
//freopen("in.txt", "r", stdin);
while (scanf("%d%d", &n, &m), n && m)
{
int total = ; //输入字母总个数
bool flag = false; //得到结论
memset(letter, , sizeof(letter));
for (int i = ; i <= m; i++)
{
char formula[];
scanf("%s", formula);
if (flag) continue; //已得出结论
int small = formula[] - 'A';
int big = formula[] - 'A';
total += !letter[small].v + !letter[big].v;
letter[small].v = letter[big].v = ;
letter[small].p.push_back(big);
letter[big].in++;
int key = topSort(total);
if (key == -)
{
printf("Inconsistency found after %d relations.\n", i);
flag = true;
}
else if (key == )
{
printf("Sorted sequence determined after %d relations: %s.\n", i, seq);
flag = true;
}
}
if (!flag)
printf("Sorted sequence cannot be determined.\n");
}
return ;
}
POJ2585(ZOJ2193)-Window Pains
题意:给定一组出现在固定位置的预设窗口,求可否使得这些窗口按照先后次序得到给定样例的显示状态。
题解:拓扑排序,用覆盖表示先后关系,若最终无环则可以按照一定次序得到样例,如果有环,那么就与覆盖这种单向关系矛盾。
//拓扑排序-窗口覆盖问题
//单向关系问题
//Time:16Ms Memory:176K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std; #define MAX 4 //预设窗口
struct Map {
int size; //覆盖个数
int num[MAX];
}map[MAX][MAX]; struct Area {
vector<int> cover;
int in; //入度
}area[]; int win[MAX][MAX]; //实际窗口
int mov[][] = { {,}, {,}, {,}, {,} }; void init()
{
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
for (int k = ; k < ; k++)
{
int tx = i + mov[k][];
int ty = j + mov[k][];
map[tx][ty].num[map[tx][ty].size++] = i * + j + ;
}
} //拓扑排序
bool topology()
{
for (int i = ; i < ;i++)
{
int cur = ;
while (++cur < && area[cur].in); //找出入度为0的点
if (cur == ) return false; //存在环-非单向关系
area[cur].in--; vector<int> cover = area[cur].cover;
for (int i = ; i < cover.size(); i++)
area[cover[i]].in--;
}
return true;
} int main()
{
init(); char command[];
while (scanf("%s", command), strcmp(command, "ENDOFINPUT"))
{
memset(area, , sizeof(area));
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
scanf("%d", &win[i][j]);
scanf("%s", command); //Area-Cover
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
for (int k = ; k < map[i][j].size; k++)
{
vector<int> cover = area[win[i][j]].cover;
int num = map[i][j].num[k];
if (num != win[i][j] && cover.end() == find(cover.begin(), cover.end(), num)) //去重
{
area[win[i][j]].cover.push_back(num);
area[num].in++;
}
} if (topology())
printf("THESE WINDOWS ARE CLEAN\n");
else printf("THESE WINDOWS ARE BROKEN\n");
} return ;
}
ACM/ICPC 之 拓扑排序范例(POJ1094-POJ2585)的更多相关文章
- ACM/ICPC 之 拓扑排序-反向(POJ3687)
难点依旧是题意....需要反向构图+去重+看题 POJ3687-Labeling Balls 题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重 ...
- ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083)-POJ1270)
两道经典的同类型拓扑排序+DFS问题,第二题较第一题简单,其中的难点在于字典序输出+建立单向无环图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacki ...
- ACM: hihicoder #1174 : 拓扑排序·一 STL- queue
#1174 : 拓扑排序·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来. 小Ho:小Hi,你这学期有选 ...
- ACM/ICPC 之 最短路径-dijkstra范例(ZOJ2750-POJ1135(ZOJ1298))
最短路经典算法-dijkstra范例(两道),第一道是裸的dijkstra,第二道需要枚举所有边已找到可能的情况. ZOJ2750-Idiomatic Phrases Game 题意:见Code 题解 ...
- ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TSH OJ-旅行商TSP)
做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(T ...
- nyoj349 poj1094 Sorting It All Out(拓扑排序)
nyoj349 http://acm.nyist.net/JudgeOnline/problem.php?pid=349poj1094 http://poj.org/problem?id=10 ...
- POJ1094 拓扑排序
问题:POJ1094 本题考查拓扑排序算法 拓扑排序: 1)找到入度为0的点,加入已排序列表末尾: 2)删除该点,更新入度数组. 循环1)2)直到 1. 所有点都被删除,则找到一个拓扑 ...
- [ACM] hdu 1285 确定比赛 (拓扑排序)
确定比赛 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- [poj1094]Sorting It All Out_拓扑排序
Sorting It All Out poj-1094 题目大意:给出一些字符串之间的大小关系,问能否得到一个唯一的字符串序列,满足权值随下标递增. 注释:最多26个字母,均为大写. 想法:显然,很容 ...
随机推荐
- vim 配置,我本机的配置[windows]
set nocompatible source $VIMRUNTIME/vimrc_example.vim source $VIMRUNTIME/mswin.vim behave mswin set ...
- java读写excel文件
近期处理的数据规模比较大,正好又是统计合并的事情,想着借助excel就可以完成了,然后就了解了下java读取excel的事情. 读取的文件主要分两类:xls文件.xlsx文件.xls文件的相关操作用的 ...
- jquery音乐播放器(歌词滚动版)
好久没出来水了!!!忙忙碌碌的找工作~然后中秋节也算过了,祝各位coding们,直接觉醒第七感小宇宙,直接用心就能找到bug-_-// 最后如题这是一篇很正规的coding的文章 大概么比以前的加了个 ...
- Python XML解析(转载)
Python XML解析 什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). 你可以通过本站学习XML教程 XML 被设计用来传输和存储数据. XML是 ...
- SQL获取日期格式
) + ' ' + CONVERT(VARCHAR, DATEPART(hh, GetDate())) + ':' + ) AS Date ),) ),) ),) as DateTime) as [D ...
- EasyUI中datagrid控件的使用 设置多行表头(两行或多行)
EasyUI中的datagrid控件十分强大,能生成各种复杂的报表,现在因为项目需要,需要生成一个表头两行的表,找了一些说明文档,以下用一个实例来说明一下: 第一种方法: $('#divData'). ...
- 各大互联网公司前端面试题(js)
对于巩固复习js更是大有裨益. 初级Javascript: 1.JavaScript是一门什么样的语言,它有哪些特点? 没有标准答案. 2.JavaScript的数据类型都有什么? 基本数据类型 ...
- Redis优化之CPU充分利用
Linux Redis Server之CPU充分利用 不知道大家有没有注意到你们公司的集群配置是否是有一种配置是这样的: 多个Redis Server分布在同一个节点,只是端口不同,如果有的话,应该是 ...
- All Kind Of Conference(随时更新...)
收集一些前端开发的各种会议,里面有视频或者PPT,随时查看都还是很有收获的.还有要向这些演讲的前辈看齐- AC 2015:http://ac.alloyteam.com/2015/ AC 2016:h ...
- 2016年11月19日--连接查询,变量、if else、while
连接查询:通过连接运算符可以实现多个表查询.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 常用的两个链接运算符: 1.join on 2.union 在关 ...