两道拓扑排序问题的范例,用拓扑排序解决的实质是一个单向关系问题


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)的更多相关文章

  1. ACM/ICPC 之 拓扑排序-反向(POJ3687)

    难点依旧是题意....需要反向构图+去重+看题 POJ3687-Labeling Balls 题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重 ...

  2. ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083)-POJ1270)

    两道经典的同类型拓扑排序+DFS问题,第二题较第一题简单,其中的难点在于字典序输出+建立单向无环图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacki ...

  3. ACM: hihicoder #1174 : 拓扑排序·一 STL- queue

    #1174 : 拓扑排序·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来. 小Ho:小Hi,你这学期有选 ...

  4. ACM/ICPC 之 最短路径-dijkstra范例(ZOJ2750-POJ1135(ZOJ1298))

    最短路经典算法-dijkstra范例(两道),第一道是裸的dijkstra,第二道需要枚举所有边已找到可能的情况. ZOJ2750-Idiomatic Phrases Game 题意:见Code 题解 ...

  5. ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TSH OJ-旅行商TSP)

    做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(T ...

  6. nyoj349 poj1094 Sorting It All Out(拓扑排序)

    nyoj349   http://acm.nyist.net/JudgeOnline/problem.php?pid=349poj1094   http://poj.org/problem?id=10 ...

  7. POJ1094 拓扑排序

    问题:POJ1094   本题考查拓扑排序算法   拓扑排序:   1)找到入度为0的点,加入已排序列表末尾: 2)删除该点,更新入度数组.   循环1)2)直到 1. 所有点都被删除,则找到一个拓扑 ...

  8. [ACM] hdu 1285 确定比赛 (拓扑排序)

    确定比赛 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. [poj1094]Sorting It All Out_拓扑排序

    Sorting It All Out poj-1094 题目大意:给出一些字符串之间的大小关系,问能否得到一个唯一的字符串序列,满足权值随下标递增. 注释:最多26个字母,均为大写. 想法:显然,很容 ...

随机推荐

  1. 总结一下安装linux系统经验-版本选择-安装ubuntu

    linux版本选择: 初次接触,建议选 Ubuntu 或者 Fedora,这两个发行版都很容易上手,而且两者都有很强大的中文社区,遇到问题比较容易解决,而且都有国内的源,安装或者更新软件时体验相对会好 ...

  2. 昨天所写的JQ 点击隐藏事件,关键性原理

    JQ 点击隐藏事件,关键性原理 1.JQ 库的调用 一般选择为: 1)库越小越好 2)库的功能越强大越好 <script src="js/jquery.js" type=&q ...

  3. iframe和frameset的使用

    iframe是:inner frame的缩写, 必须指明src属性,不能直接在里面写内容, 否则不会显示. 可以载入html, *.图片文件, txt文件等等. html的属性中,表示长度高度的尺寸属 ...

  4. centos 安装 mysql5.6

    转载自 http://www.cnblogs.com/littlehb/archive/2013/04/02/2995007.html Mysql 5.5以后使用了CMake进行安装,参考与以前的区别 ...

  5. 安装好Android Studio(如果内存足够可以改下as的内存)

    找到studio的bin目录,找到如下文件

  6. MySQL也有潜规则 – Select 语句不加 Order By 如何排序?

    今天遇到一个问题,有一个 Select 语句没有加 "Order By",返回的数据是不确定的. 这种问题碰到不止几次了.追根寻底, Select 语句如果不加 "Ord ...

  7. div+css模仿登录界面

    我的代码,这种方式形成了遮罩层,遮罩层的"登录"按钮仍可被点击,非我想要的. <!DOCTYPE html> <html lang="en"& ...

  8. ubuntu下修改apache2.4的rewrite

    sudo a2enmod rewrite 修改/etc/apache2/apache2.conf中 AllowOverride None 为 AllowOverride ALL 重启 service ...

  9. CSS3必须要知道的10个顶级命令

    1.边框圆角(Border Radiuas) 这个是我们在平常很常用的吧,以前我在用div圆角的时候,特别特别的痛苦,不管是用CSS来画圆角,还是用图片来画圆角都不那么容易,但是现在好了,在CSS3中 ...

  10. Code First05--CodeFirst中值对象

    今天主要介绍EF Code First中一个高级部分:Value Object,中文翻译过来叫做值对象. 所谓的值对象就是一些没有生命周期,也没有业务逻辑上唯一标识符的类.哪些类是Entity,哪些类 ...