/* (⊙v⊙)嗯 貌似是一个建图 拓扑+深搜的过程。至于为什么要深搜嘛。。一个月前敲得题现在全部推了重敲,于是明白了。因为题意要求如果有多个可能的解的话。
 * 就要输出字典序最小的那个。所以可以对26个英文字母从小到大尝试能否排出结果。于是出现了 深搜回溯。先选定入度为0的边框。标记为已用。将所有与它连通的
 * 边框入度减一。然后递归搜索下一个。此时开始回溯。当前边框标记为未用,所有与它连通的边框入度加1.
 * 建图的过程则是。对每一个字母的边框测量出来。然后对A里的其它字母B。(B 覆盖 A)。有关系 map[A][B] = *1。in[B]++;
 */

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 27

int map[maxn+5][maxn+5];    //建的图
char m[35][35];     //输入
int h, w;     // 输入size
int tot;  //有多少种字母边框
int in[maxn];  //每种字母对应的入度。
char ans[maxn];   // 存储答案
bool flag;

struct Node   // 存储每个字母对应的边框边界
{
    int lo, hi;
    int le, ri;
}node[maxn+5];

void buildmap()
{
    for (int i=0; i<h; ++i)  // 测量边界
    {
        for (int j=0; j<w; ++j)
        {
            if (m[i][j] == '.')
                continue;
            int temp = m[i][j] - 'A';
            if (in[temp] == -1)
            {
                in[temp] = 0;
                tot++;
            }
            if (i > node[temp].hi) node[temp].hi = i;
            if (i < node[temp].lo) node[temp].lo = i;
            if (j < node[temp].le) node[temp].le = j;
            if (j > node[temp].ri) node[temp].ri = j;
        }
    }

for (int k=0; k<maxn; ++k)   //建图
    {
        if (in[k] == -1)
            continue;
        for (int i=node[k].lo; i<=node[k].hi; ++i)
        {
            for (int j=node[k].le; j<=node[k].ri; ++j)
            {
                if (i>node[k].lo && i<node[k].hi && j>node[k].le && j<node[k].ri)
                    continue;
                int temp = m[i][j] - 'A';
                if (k != temp && !map[k][temp])
                {
                   map[k][temp] = 1;
                   in[temp] += 1;
                }
            }
        }
    }
}
int hh = 0;

void dfs(int num)
{
    if (num == tot)
    {
        ans[num] = '\0';
        cout << ans << endl;
        return;
    }

//觉得应该会有字典序不同的答案。所以在输出加上判断。然而。wa了。应该是递归没有理解清楚。
//    if (num == tot && flag)
//    {
//        ans[num] = '\0';
//        puts(ans);
//        flag = false;
//        return;
//    }

for (int i=0; i<maxn; ++i)
    {
        if (in[i] == 0)
        {
            ans[num] = i + 'A';
            in[i] = -1;
            for (int j=0; j<maxn; j++)
            {
               if (map[i][j])
                 in[j] -= 1;
            }
            dfs(num+1);
            in[i] = 0;
            for (int j=0; j<maxn; ++j)
            {
               if (map[i][j])
                 in[j] += 1;
            }
        }
    }
    return;
}

int main()
{
    while (scanf("%d%d", &h, &w) == 2)
    {
        tot = 0;
        memset(in, -1, sizeof(in));
        memset(map, 0, sizeof(map));
        flag = true;
        for (int i=0; i<maxn+5; ++i)
        {
            node[i].lo = 100;
            node[i].le = 100;
            node[i].hi = -1;
            node[i].ri = -1;
        }
        for (int i=0; i<h; ++i)
        {
            scanf("%s", m[i]);
        }
        buildmap();
        dfs(0);
    }
    return 0;
}

POJ 1128 拓扑排序 + 深搜的更多相关文章

  1. poj 3687(拓扑排序)

    http://poj.org/problem?id=3687 题意:有一些球他们都有各自的重量,而且每个球的重量都不相同,现在,要给这些球贴标签.如果这些球没有限定条件说是哪个比哪个轻的话,那么默认的 ...

  2. POJ 3249 拓扑排序+DP

    貌似是道水题.TLE了几次.把所有的输入输出改成scanf 和 printf ,有吧队列改成了数组模拟.然后就AC 了.2333333.... Description: MR.DOG 在找工作的过程中 ...

  3. poj 3249 拓扑排序 and 动态规划

    思路:我们首先来一遍拓扑排序,将点按先后顺序排列于一维数组中,然后扫描一遍数组,将每个点的出边所连接的点进行更新,即可得到最优解. #include<iostream> #include& ...

  4. poj 2585 拓扑排序

    这题主要在于建图.对9个2*2的小块,第i块如果出现了不等于i的数字,那么一定是在i之后被brought的.可以从i到该数字建一条边. 图建好后,进行一次拓扑排序,判段是否存在环.若存在环,那么就是B ...

  5. Sorting It All Out POJ - 1094 拓扑排序

    题意:给N个字母,和M个偏序关系 求一个可确定的全序,可确定是指没有其他的可能例如A>B D>B 那么有ADB DAB两种,这就是不可确定的其中,M个偏序关系可以看做是一个一个按时间给出的 ...

  6. poj 3984 -- 迷宫问题 深搜

    迷宫问题 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, ...

  7. nyoj 349 (poj 1094) (拓扑排序)

    Sorting It All Out 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 An ascending sorted sequence of distinct ...

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

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

  9. Poj(3687),拓扑排序,

    题目链接:http://poj.org/problem?id=3687 题意:n个重量为1~n的球,给定一些编号间的重量比较关系,现在给每个球编号,在符合条件的前提下使得编号小的球重量小.(先保证1号 ...

随机推荐

  1. 20145304 Exp4 恶意代码分析

    20145304 Exp4 恶意代码分析 实验后回答问题 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控 ...

  2. 20145335郝昊《网络攻防》Exp4 Msf基础

    20145335郝昊<网络攻防>Exp4 Msf基础 实验内容 掌握metasploit的基本应用方式,掌握常用的三种攻击方式的思路. 一个主动攻击,如ms08_067; 一个针对浏览器的 ...

  3. Matchvs 使用记录

    Matchvs Matchvs视频教程. https://doc.matchvs.com/VideoTutorials/videogs matchvs下载资源. http://www.matchvs. ...

  4. xshell5 Linux 上传下载文件

    1,先登录身份验证和文件传输ZMODEM 选择自动激活. 2,rpm -qa | grep lrzsz 利用此命令查看是否安装了lrzsz . 如果没有任何反应则是没有安装 若没有安装 yum ins ...

  5. C#学习笔记(十一):类和对象

    面向对象 为什么要面向对象: 1.和函数一样,把算法封装起来,方便复用 2.更好理解自己和别人写的代码 封装:数据.结构.逻辑的封装,方便复用 多态:同一个对象,同一种指令,不同的行为(反应) 继承: ...

  6. java web项目去除项目名称访问设置方法及tomcat的<Host>标签讲解

    本文为博主原创,未经允许不得转载. 在集群项目中,为了方便用户可以更快捷的访问,即只需要输入IP和端口号,就可以直接访问项目,因为 模块比较多,记住项目名称并不容易,所以在网上查看和学习了下设置的方法 ...

  7. springmvc基础知识及注解

    SpringMVC 1.概念 Spring的MVC框架是一个基于DispatcherServlet的MVC框架,主要由DispatcherServlet.处理器映射.处理器.视图解析器.视图组成.每一 ...

  8. 02_HBase集群部署

    HBase集群部署 HBase是分布式数据库,本身也需要借助zookeeper进行集群节点间的协调(Master, RegionServer), 可以使用HBase自带的zookeeper,也可以使用 ...

  9. 51nod 1444 破坏道路(最短路)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1444 题意: 思路: 哇,思路爆炸. 因为每条边的权值都为1,所以可以直 ...

  10. WCF 统一处理异常利用行为服务扩展

    https://www.cnblogs.com/niaowo/p/4727378.html using System; using System.Collections.Generic; using ...