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

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

输出方案要麻烦一些,最刚开始还没有想到。可以用一个$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. shell小命令

    小括号的用途 cd ..; ls -l (cd ..; ls -l) 如果加了括号,则当前工作目录不发生改变 shell变量类型 环境变量 可以使用 echo  或者env 例如 env|grep 变 ...

  2. Python模拟浏览器前进后退操作

    # 模拟浏览器前进后退操作 # 代码中引入selenium版本为:3.4.3 # 通过Chrom浏览器访问发起请求 # Chrom版本:59 ,chromdriver:2.3 # 需要对应版本的Chr ...

  3. 设计一个Mypoint类,求两个点之间的距离

    package Test; public class test6 { public static void main(String[] args) { // TODO Auto-generated m ...

  4. JVM(九),垃圾回收回收算法

    九.垃圾回收回收算法 1.标记-清除(Mark and Sweep) 缺点是内存空间碎片化太严重 2.复制算法(Copying) (1)复制算法介绍 (2)复制算法优势 3.标记-整理算法(Compa ...

  5. C/C++ - malloc/free和new/delete的区分

    new/delete与malloc/free的区别主要表现在以下几个方面: 注意:最主要的区别,new/delete是运算符,而malloc/free是函数 (1).new能够自动计算需要分配的内存空 ...

  6. Unity3D面试问题

    注意,是问题,不是笔试题哦.这些是我最近面试北京各公司总结的一些被问到的还算典型的问题.跟大家分享一下.答案是我自己的,不保证标准和完整. 哎,公司年底开人,又校招一群便宜的小鬼……桑死心了……好在找 ...

  7. Js模块化开发--seajs和gruntJs

    1.Seajs库 解决开发中的冲突依赖等问题,提供代码可维护性. SeaJS 是由玉伯开发的一个遵循 CommonJS 规范的模块加载框架,可用来轻松愉悦地加载任意 JavaScript 模块和css ...

  8. Codeforces Gym Joyride(分层图,dijkstra)

    题意:有一张图,每条边有一个边权t表示经过所花时间,每个点有两个权t.p,分别表示经过该点所花时间和所花费用,要求找一条路径,从点1出发再回到点1,所花时间恰好为x且费用最小,输出其费用,找不到则输出 ...

  9. Vue_(组件通讯)父子组件简单关系

    Vue组件 传送门 在Vue的组件内也可以定义组件,这种关系成为父子组件的关系 如果在一个Vue实例中定义了component-a,然后在component-a中定义了component-b,那他们的 ...

  10. HDU 5858 Hard problem ——(计算几何)

    其实这题最多是个小学奥数题- -,,看到别人博客各显神通,也有用微积分做的(我也试了一下,结果到最后不会积...). 思路如下(这两张图是网上找来的): 然后就很简单了,算三角形面积可以用海伦公式,也 ...