题意居然还读了好久...

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

输出方案要麻烦一些,最刚开始还没有想到。可以用一个$dfs$,当这个点的入度变为$0$之后,就输出,递归到下一层,然后再回溯。按字母的字典序枚举就可以输出按字典序排的方案。

 /*
ID: Starry21
LANG: C++
TASK: frameup
*/
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define N 35
int h,w,n/*一共n个图像(字母)*/;
char mp[N][N];//存图
int s[N],x[N],z[N],y[N];//每个字母边框的上下左右边在哪一行(列)
char kd[N];//存字母(1~n)
bool vis[N];//各种标记 看地方 vector<int>G[N];//拓扑的边
int ind[N];//入度
char ans[N];
void dfs(int k)
{
//printf("%d\n",k);
if(k>n)
{
for(int i=;i<=n;i++)
printf("%c",ans[i]);
puts("");
return ;
}
for(int i=;i<=n;i++)
if(ind[kd[i]-'A']==&&!vis[i])
{
vis[i]=;
ans[k]=kd[i];
for(int j=;j<G[kd[i]-'A'].size();j++)
{
int v=G[kd[i]-'A'][j];
ind[v]--;
}
dfs(k+);
vis[i]=;
for(int j=;j<G[kd[i]-'A'].size();j++)
{
int v=G[kd[i]-'A'][j];
ind[v]++;
}
}
}
int main()
{
//freopen("frameup.in","r",stdin);
//freopen("frameup.out","w",stdout);
scanf("%d %d",&h,&w);
for(int i=;i<=h;i++)
{
scanf("%s",mp[i]+);
for(int j=;j<=w;j++)
{
if(mp[i][j]=='.') continue;
if(!vis[mp[i][j]-'A'])
{
kd[++n]=mp[i][j];
vis[mp[i][j]-'A']=;
}
if(!s[mp[i][j]-'A']) s[mp[i][j]-'A']=i;
if(!z[mp[i][j]-'A']) z[mp[i][j]-'A']=j;
if(!x[mp[i][j]-'A']) x[mp[i][j]-'A']=i;
if(!y[mp[i][j]-'A']) y[mp[i][j]-'A']=j;
s[mp[i][j]-'A']=min(s[mp[i][j]-'A'],i);
z[mp[i][j]-'A']=min(z[mp[i][j]-'A'],j);
x[mp[i][j]-'A']=max(x[mp[i][j]-'A'],i);
y[mp[i][j]-'A']=max(y[mp[i][j]-'A'],j);
/*
题目保证方块的每一条边都有露出来的
所以直接取min/max就好
*/
}
}
/*for(int i=1;i<=n;i++)
{
printf("%c\n",kd[i]);
int id=kd[i]-'A';
printf("%d %d %d %d\n",s[id],x[id],z[id],y[id]);
}*/
memset(ind,-,sizeof(ind));//排除无关字母
for(int i=;i<=n;i++)
ind[kd[i]-'A']=;
for(int i=;i<=n;i++)//枚举字母
{
memset(vis,,sizeof(vis));//清空 标记这个点连了哪些 不连重边
int id=kd[i]-'A';
for(int j=z[id];j<=y[id];j++)
if(mp[s[id]][j]!=kd[i]&&!vis[mp[s[id]][j]-'A'])
{
G[id].push_back(mp[s[id]][j]-'A');
vis[mp[s[id]][j]-'A']=;
ind[mp[s[id]][j]-'A']++;
}
for(int j=z[id];j<=y[id];j++)
if(mp[x[id]][j]!=kd[i]&&!vis[mp[x[id]][j]-'A'])
{
G[id].push_back(mp[x[id]][j]-'A');
vis[mp[x[id]][j]-'A']=;
ind[mp[x[id]][j]-'A']++;
}
for(int j=s[id];j<=x[id];j++)
if(mp[j][z[id]]!=kd[i]&&!vis[mp[j][z[id]]-'A'])
{
G[id].push_back(mp[j][z[id]]-'A');
vis[mp[j][z[id]]-'A']=;
ind[mp[j][z[id]]-'A']++;
}
for(int j=s[id];j<=x[id];j++)
if(mp[j][y[id]]!=kd[i]&&!vis[mp[j][y[id]]-'A'])
{
G[id].push_back(mp[j][y[id]]-'A');
vis[mp[j][y[id]]-'A']=;
ind[mp[j][y[id]]-'A']++;
}
}
sort(kd+,kd+n+);
memset(vis,,sizeof(vis));
dfs();//按照拓扑排序 入度为0之后可以选也可以不选 题目保证有解
return ;
}

Code

USACO4.4 Frame Up【拓扑排序】的更多相关文章

  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. Frame Stacking(拓扑排序)

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

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

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

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

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

  7. POJ1128 Frame Stacking(拓扑排序)

    题目链接:http://poj.org/problem?id=1128 题意:给你一个平面,里面有些矩形(由字母围成),这些矩形互相有覆盖关系,请从求出最底层的矩形到最上层的矩形的序列,如果存在多种序 ...

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

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

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

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

随机推荐

  1. hadoop中的JournalNode

    1.在HADOOP扮演的角色 JournalNode是在MR2也就是Yarn中新加的,journalNode的作用是存放EditLog的, 在MR1中editlog是和fsimage存放在一起的然后S ...

  2. Linux 一键部署脚本

    在当前路径下输入 chmod 777 脚本名 给脚本授权, 然后就可以执行脚本 ./脚本名    777 是最高权限,有读.写.执行权限:和属组用户和其他用户的读.写.执行权限. 其他权限分别是 -r ...

  3. 【agc002f】Leftmost Ball

    题目大意 有n种颜色,每种k个球.将这些球任意排列,将每种颜色中最前面的一个求涂成白色(就是n+1种颜色),求最终的排列的方案的个数. 解题思路 考虑如何计算不会算重, 按颜色顺序,每次往排列插入k个 ...

  4. 炫酷CSS3垂直时间轴特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 【leetcode】1287. Element Appearing More Than 25% In Sorted Array

    题目如下: Given an integer array sorted in non-decreasing order, there is exactly one integer in the arr ...

  6. CentOS8编译openocd-0.10.0

    1.sudo yum install libusbx-devel 2. ./configure --prefix=$HOME/openocd-0.10.0 --enable-jlink CFLAGS= ...

  7. jQuery的replaceWith()函数用法详解

    replaceWith,替换元素 replaceWith() 方法将选择的元素的内容替换为其他内容. 我们先在先看一个实例 <!DOCTYPE html> <html> < ...

  8. Python基础之Python介绍

    Python的创始人为吉多·范罗苏姆(Guido Van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承. 最新 ...

  9. jQuery事件之解绑事件

    语法: $(selector).unbind([eventType][,handler(eventObject)]); 返回值:jQuery 参数解释: eventTypey:类型:String以后包 ...

  10. FRP

    使用 FRP 反向代理实现 Windows 远程连接 互联网普及率的日渐攀升与 IPv4 资源的持续减少,现在大部分家庭宽带都不会分配公网 IP ,这使一些网络应用的实现多了些困难,像个人的 NAS ...