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


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. zookeeper运维 --【】转】

     from:http://blog.csdn.net/hengyunabc/article/details/19006911  zookeeper运维 尽管zookeeper在编程上有很多的阱陷,AP ...

  2. word中替换被批注的正文的值

    word中替换被批注的正文的值   word批注winform替换值正文             try            {                Word.Document docum ...

  3. Jquery 操作IFrame

    使用jquery操作iframe 1. 内容里有两个ifame <iframe id="leftiframe"...</iframe> <iframe id ...

  4. WCF--提示:"未找到终结点。"

    刚开始调用WCF的时候一直报错... ““System.ServiceModel.EndpointNotFoundException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进 ...

  5. ASP页面-自动取回数据库中的值生成导航。

    以下为自己总结的一点经验,简单的介绍一下方法,如发现有误,请帮忙指正,谢谢. 一,首先定义调用据库. <% dim objconn,objconnstr set objconn=server.c ...

  6. IGV软件

    它支持各种各样的数据类型,包括基于芯片测序.二代测序数据和基因组注释数据等.整合基因组浏览器(IGV,Integrative Genomics Viewer)进行可视化浏览,它支持各种各式的数据类型, ...

  7. 6.3.28微信需群主确认才可进群&发GIF动图功能内测开始了

    昨天下午有网友收到微信6.3.28新版内测邀请,不过这个内部体验目前貌似只对安卓手机开放,苹果的IOS系统还不支持,会提示“你当前使用的是非安卓设备,不建议下载安卓体验包,但你仍可邀请朋友尝鲜”.最新 ...

  8. 微信电话本可免费拨打网络电话 通话一分钟约300K流量

    微信电话本新版本于昨日晚间发布,这是一款智能通讯增强软件,通话双方都下载此APP并开通免费通话功能就能使用微信电话本拨打免费网络电话,在对方无法接通情况下还能将音频转向语音信箱,微信电话本目前支持An ...

  9. 2.交通聚类 -层次聚类(agnes)Java实现

    1.项目背景 在做交通路线分析的时候,客户需要找出车辆的行车规律,我们将车辆每天的行车路线当做一个数据样本,总共有365天或是更多,从这些数据中通过聚类来获得行车路线规律统计分析. 我首先想到是K-m ...

  10. Ubuntu 14 安装 “宋体,微软雅黑,WPS Office的symbol、wingdings、wingdings 2、wingdings 3、webding字体,Consolas雅黑混合版编程字体” 等 Windows 7 下的字体

    Windows平台下,“宋体”.“微软雅黑”.“Courier New(编程字体)”用的比较多,看的也习惯了.那如何在 Ubuntu下也安装这些字体呢? 操作步骤如下: 第一步:从 Windows 7 ...