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

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

输出方案要麻烦一些,最刚开始还没有想到。可以用一个$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. HTTP协议几个版本的理解

    HTTP (HyperText transfer protocol) 超文本传输协议 Http是一个应用层协议,基于TCP协议(传输层)之上,规定WWW服务器 浏览器之间信息传递规范.使用的默认端口号 ...

  2. idea设置数据库连接所有项目都能看到

    首先打来配置好数据库的项目,打开database视图,点击配置. 点击 Project Data Soures 下配置好的数据库,然后点击 Make Global ,然后就可以在其他项目看到该数据库连 ...

  3. 线程安全 Vs 非线程安全

    线程安全:多线程访问时,采用了加锁机制,当一个线程读取数据时,其他线程不能访问直到该线程读取完毕.不会出现数据不一致或者脏数据. 非线程安全:不提供数据保护,可能出现其他线程访问时更改数据而该线程得到 ...

  4. vue学习时遇到的问题(二)

    1. this.$nextTick veu中进行数据改变后,并不会马上刷新视图:用nextTick可告诉执行下个函数后马上刷新视图: this.$nextTick(function(){     // ...

  5. Confluence 6.15 博客页面(Blog Posts)宏

    博客页面宏允许你 Confluence 页面中显示博客页面.通过单击博客的标题将会把你链接到博客页面中. 使用博客页面宏 为了将博客页面宏添加到页面中:  从编辑工具栏中,选择 插入(Insert)  ...

  6. luoguP1160 队列安排 x

    P1160 队列安排 982通过 2.3K提交 题目提供者 该用户不存在 标签 云端 难度 普及/提高- 时空限制 1s / 128MB 题目描述 一个学校里老师要将班上N个同学排成一列,同学被编号为 ...

  7. 包管理神器-pipenv

    一:前言 介绍一个包管理神器-pipenv,这个工具可以让我们在写代码.创建Python运行环境.package依赖关系以及项目合作的时候更有效率. 在pycon2018上,Kenneth Reitz ...

  8. SpringMVC——MVC执行流程底层剖析

    SpringMVC流程图如上面所示,根据上图,串联一下底层源码: 1.在DispatcherServlet中找到doDisPatch 2.观察方法体,然后找到getHandler方法 3.点进方法,发 ...

  9. Codeforces 963 A. Alternating Sum(快速幂,逆元)

    Codeforces 963 A. Alternating Sum 题目大意:给出一组长度为n+1且元素为1或者-1的数组S(0~n),数组每k个元素为一周期,保证n+1可以被k整除.给a和b,求对1 ...

  10. MySQL_(Java)【事物操作】使用JDBC模拟银行转账向数据库发起修改请求

    MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC向数据库中插入(insert)数据 传送门 MySQL_(Java)使用JDBC向数据库中删除(d ...