题目链接:http://poj.org/problem?id=1128

题意:给你一个平面,里面有些矩形(由字母围成),这些矩形互相有覆盖关系,请从求出最底层的矩形到最上层的矩形的序列,如果存在多种序列,答案按照字典序依次输出。

思路:这道题的难点在建图,利用矩形之间的覆盖关系建图,说着容易,实际上仔细想想不太容易。由于矩形的任意一个边界不会完全被覆盖,所以我们可以确定一个矩形的上下左右边界,然后对每个矩形的上下左右边界扫一遍,看是否被其他字母所覆盖,利用覆盖关系建图。这里无法利用队列的方式拓扑排序,因为要输出所有的序列,所以dfs的方式更为出色,具体的注释都写在代码里面了。

//Author: xiaowuga
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <map>
#include <bitset>
#include <cctype>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
#define mem(s,ch) memset(s,ch,sizeof(s))
#define da cout<<"da"<<endl
#define uoutput(a,i,l,r) for(int i=l;i<r;i++) if(i==l) cout<<a[i];else cout<<" "<<a[i];cout<<endl;
#define doutput(a,i,l,r) for(int i=r-1;i>=0;i--) if(i==r-1) cout<<a[i];else cout<<" "<<a[i];cout<<endl;
const long long N=;
using namespace std;
typedef long long LL;
int L[N],R[N],U[N],D[N],in[N],vis[N],v[N];
//L左边界数组,R有边界数组,U上边界数组,D下边界数组
//vis字母存在数组,v是dfs中是否访问数组
char pic[N][N],ans[N];
int p[N][N];
int n,m,ct;
//初始化
void init(){
ct=;//存在字母总数量初始化为0
mem(in,);//入度数组初始化为0
mem(vis,);//字母存在数组初始化为0
mem(v,);
mem(p,);//邻接矩阵初始化为0
//上左边界最大化,下右边界最小化
mem(L,inf);mem(U,inf);mem(R,-);mem(D,-);
}
void make_g(int i,int j,int k){
int t=pic[i][j]-'A';
if(k!=t){
if(!p[k][t]) {p[k][t]=;in[t]++;}
}
}
void dfs(int x,int y){
ans[y]=x+'A';
v[x]=;//标记为访问过
if(y==ct){//全部字母已经排好拓扑序
for(int i=;i<=ct;i++) cout<<ans[i];cout<<endl;//输出
v[x]=;//恢复
return ;
}
int q[N],num=;
//i从0-26保证了字典序
for(int i=;i<;i++){
if(p[x][i]) --in[i];//存在连接则连接减少入度
if(vis[i]&&!in[i]&&!v[i]) q[num++]=i;//存在连接且入度减为0,且未访问
}
//对所有后续节点进行dfs
for(int i=;i<num;++i) dfs(q[i],y+);
for(int i=;i<;i++) if(p[x][i]) in[i]++;//恢复
v[x]=;//恢复
}
void topo(){
for(int i=;i<;++i) if(vis[i]&&!in[i]) dfs(i,);
}
int main() {
ios::sync_with_stdio(false);cin.tie();
while(cin>>n>>m){
init();
//输入整个图形并确定每个矩形的上下左右边界
for(int i=;i<n;++i) for(int j=;j<m;++j){
cin>>pic[i][j];
if(pic[i][j]!='.'){
int t=pic[i][j]-'A';
if(!vis[t]){ vis[t]=;ct++;}
L[t]=min(L[t],j);
R[t]=max(R[t],j);
U[t]=min(U[t],i);
D[t]=max(D[t],i);
}
}
for(int k=;k<;k++){
if(vis[k]){
int i,j;
i=U[k];//上边界上
for(j=L[k];j<=R[k];j++) make_g(i,j,k);
i=D[k];//下边界上
for(j=L[k];j<=R[k];j++) make_g(i,j,k);
j=L[k];//左边界上
for(i=U[k]+;i<D[k];i++) make_g(i,j,k);
j=R[k];//右边界上
for(i=U[k]+;i<D[k];i++) make_g(i,j,k);
}
}
topo();
}
return ;
}

POJ1128 Frame Stacking(拓扑排序)的更多相关文章

  1. POJ 1128 Frame Stacking (拓扑排序)

    题目链接 Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ...

  2. Frame Stacking 拓扑排序 图论

    Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ .... ...

  3. POJ 1128 Frame Stacking 拓扑排序+暴搜

    这道题输出特别坑.... 题目的意思也不太好理解.. 就解释一下输出吧.. 它让你 从下往上输出. 如果有多种情况,按照字典序从小往大输出... 就是这个多种情况是怎么产生的呢. 下面给一组样例. 很 ...

  4. POJ1128 Frame Stacking(拓扑排序+dfs)题解

    Description Consider the following 5 picture frames placed on an 9 x 8 array.  ........ ........ ... ...

  5. 图论之拓扑排序 poj1128 Frame Stacking

    题目网址 http://poj.org/problem?id=1128 思路:遍历找出每一种字母出现的最大和最小的横纵坐标,假如本应出现字母A的地方出现了字母B,那么A一定在字母B之前,这就相当于点A ...

  6. Frame Stacking(拓扑排序)

    题目链接:http://acm.tju.edu.cn/toj/showp1076.html1076.   Frame Stacking Time Limit: 1.0 Seconds   Memory ...

  7. POJ 1128 Frame Stacking(拓扑排序&#183;打印字典序)

    题意  给你一些矩形框堆叠后的鸟瞰图  推断这些矩形框的堆叠顺序  每一个矩形框满足每边都至少有一个点可见  输入保证至少有一个解 按字典序输出全部可行解 和上一题有点像  仅仅是这个要打印全部的可行 ...

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

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

  9. USACO4.4 Frame Up【拓扑排序】

    题意居然还读了好久... 读完题目之后大概就知道拓扑排序了.用拓扑可以求出一些字母之间的关系,谁先,谁后.但是这个关系不是唯一确定的,所以就会产生多种方案(题目还要求按字典序输出所有的方案) 输出方案 ...

随机推荐

  1. CXSprite.h文件

    #ifndef __XSprite_H__ #define __XSprite_H__ #include "CocoHead.h" #define BTN_FRAME_AMOUNT ...

  2. 【C/C++语言】int 在计算机内部的存储

    int在32位计算机中占4个字节,主要是想弄清楚这4个字节的在内存中存放的顺序. #include <iostream> using namespace std; typedef stru ...

  3. CentOS 7.0 关闭firewalld防火墙指令 及更换Iptables防火墙

    CentOS 7.0 关闭firewalld防火墙指令 及更换Iptables防火墙 时间:2014-10-13 19:03:48  作者:哎丫丫  来源:哎丫丫数码网  查看:11761  评论:2 ...

  4. IOS7 隐藏状态栏 (电池栏)

    电池状态栏. //方法一(代码设置): 现在ios7已经更改为透明,并且不占用屏幕高度.其中隐藏及显示的方法如下: 在uiviewcontroller的子类下,调用:     if ([self re ...

  5. 实现在edittext中任意插入图片

    Myedittext: public class MyEditText extends EditText { public MyEditText(Context context) { super(co ...

  6. zepto与jquery冲突

    公司项目中一直用的都是zepto,但是jQuery扩展的插件比较多. jQuery有一个方法noConflict(),可以把jQuery的$改掉.var aa = $.noConflict();就用a ...

  7. oracle解惑

    1. 先在google, 论坛,metalink, online document 里搜索.     在这里提供Oracle 一些常见的连接地址,包括Oracle 下载地址,Oracle 对个人用是免 ...

  8. 基于jQuery仿Flash横向切换焦点图

    给各网友分享一款基于jQuery仿Flash横向切换焦点图.利用Flash可以制作很多漂亮的图片相册应用,今天我们要用jQuery来实现这样的效果.它是一款仿Flash的横向图片切换焦点图插件,可以自 ...

  9. 使用pjsip传输已经编码的视频

    http://blog.chinaunix.net/uid-15063109-id-4445165.html ————————————————————————————————————————————— ...

  10. Libgdx window add alpha action change the background actor alpha

    现象: Stage中包括一个Window,一个Actor,Window中加入alpha action后,Actor也随之消失:Actor加入alpha action后,不起作用. 解决: 重写draw ...