题意:

      给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少?

思路:

      水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行了,时间复杂度20*20*1024的,完全可以接受,但是被坑了,一开始怎么交都TLE,后来又写了一个BFS+DFS优化,就是跑之前先遍历一遍图,看看是不是所有的垃圾点都能遍历到,这样还是超时,无奈看了下讨论,有人说用G++交就行了,我用G++交了结果两个方法都AC了,哎!下面是两个方法的代码,比较简单,最近就是无聊,上POJ来刷刷水题,还有这个题目,可以用DP去做,还有就是可以直接求出任意两个垃圾的最短距离,然后在枚举处理垃圾顺序,枚举可以用STL的全排列,也可以搜索,这样的时间复杂度大约是N!吧,跟直接暴搜没啥区别,想试的可以敲敲试试吧。

直接BFS状态压缩暴力625

#include<queue>

#include<stdio.h>

#include<string.h>

using namespace std;

typedef struct

{

    int x ,y ,k ,t;

}NODE;

NODE xin ,tou;

int map[22][22] ,n ,m ,w;

int mark[22][22][1025];

int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};

bool ok(int x ,int y ,int k)

{

    return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];

}

int BFS(int x ,int y)

{

    queue<NODE>q;

    xin.x = x ,xin.y = y;

    xin.t = 0 ,xin.k = 0;

    memset(mark ,0 ,sizeof(mark));

    mark[xin.x][xin.y][xin.k] = 1;

    q.push(xin);

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int i = 0 ;i < 4 ;i ++)

        {

            xin.x = tou.x + dir[i][0];

            xin.y = tou.y + dir[i][1];

            xin.t = tou.t + 1;

            if(map[xin.x][xin.y] && map[xin.x][xin.y] != -1)

            xin.k = tou.k | (1 << (map[xin.x][xin.y] - 1));

            else xin.k = tou.k;

            if(ok(xin.x ,xin.y ,xin.k))

            {

                mark[xin.x][xin.y][xin.k] = 1;

                q.push(xin);

                if(xin.k == (1 << w) - 1) return xin.t;

            }

        }

    }

    return -1;

}

int main ()

{

    char str[22];

    int x ,y;

    while(~scanf("%d %d" ,&m ,&n) && n+m)

    {

        w = 0;

        for(int i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,str);

            for(int j = 1 ;j <= m ;j ++)

            {

                if(str[j-1] == '.') map[i][j] = -1;

                else if(str[j-1] == '*') map[i][j] = ++w;

                else if(str[j-1] == 'x') map[i][j] = 0;

                else x = i ,y = j ,map[i][j] = -1;

            }

        }

        w ? printf("%d\n" ,BFS(x ,y)):printf("0\n");

    }

    return 0;

}

BFS+DFS剪枝594

#include<queue>

#include<stdio.h>

#include<string.h>

using namespace std;

typedef struct

{

    int x ,y ,k ,t;

}NODE;

NODE xin ,tou;

int col[22][22] ,cmk[22][22];

int map[22][22] ,n ,m ,w;

int mark[22][22][1025];

int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};

bool ok(int x ,int y ,int k)

{

    return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];

}

int BFS(int x ,int y)

{

    queue<NODE>q;

    xin.x = x ,xin.y = y;

    xin.t = 0 ,xin.k = 0;

    memset(mark ,0 ,sizeof(mark));

    mark[xin.x][xin.y][xin.k] = 1;

    q.push(xin);

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int i = 0 ;i < 4 ;i ++)

        {

            xin.x = tou.x + dir[i][0];

            xin.y = tou.y + dir[i][1];

            xin.t = tou.t + 1;

            if(map[xin.x][xin.y] && map[xin.x][xin.y] != -1)

            xin.k = tou.k | (1 << (map[xin.x][xin.y] - 1));

            else xin.k = tou.k;

            if(ok(xin.x ,xin.y ,xin.k))

            {

                mark[xin.x][xin.y][xin.k] = 1;

                q.push(xin);

                if(xin.k == (1 << w) - 1) return xin.t;

            }

        }

    }

    return -1;

}

void DFS(int x ,int y)

{

    for(int i = 0 ;i < 4 ;i ++)

    {

        int xx = x + dir[i][0];

        int yy = y + dir[i][1];

        if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && !cmk[xx][yy] && map[xx][yy])

        {

            cmk[xx][yy] = 1;

            DFS(xx ,yy);

        }

    }

}

int main ()

{

    char str[22];

    int x ,y;

    while(~scanf("%d %d" ,&m ,&n) && n+m)

    {

        w = 0;

        for(int i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,str);

            for(int j = 1 ;j <= m ;j ++)

            {

                if(str[j-1] == '.') map[i][j] = -1;

                else if(str[j-1] == '*') map[i][j] = ++w;

                else if(str[j-1] == 'x') map[i][j] = 0;

                else x = i ,y = j ,map[i][j] = -1;

            }

        }

        memset(cmk ,0 ,sizeof(cmk));

        DFS(x ,y);

        int mk = 0;

        for(int i = 1 ;i <= n && !mk;i ++)

        for(int j = 1 ;j <= m && !mk;j ++)

        if(map[i][j] != -1 && map[i][j] && !cmk[i][j])

        mk = 1;

        if(mk)

        {

            printf("-1\n");

            continue;

        }

        w ? printf("%d\n" ,BFS(x ,y)):printf("0\n");

    }

    return 0;

}

POJ2688状态压缩(可以+DFS剪枝)的更多相关文章

  1. poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)

    Description Flip game squares. One side of each piece is white and the other one is black and each p ...

  2. uva10160(dfs+状态压缩)

    题意:给出n个点,以及m条边,这些边代表着这些点相连,修一个电力站,若在某一点修一个站,那么与这个点相连的点都可以通电,问所有的点都通电的话至少要修多少个电力站........ 思路:最多给出的是35 ...

  3. Sudoku (剪枝+状态压缩+预处理)

    [题目描述] In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. ...

  4. codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)

    B. Preparing Olympiad You have n problems. You have estimated the difficulty of the i-th one as inte ...

  5. 最大联通子数组之和(dfs,记忆化搜索,状态压缩)

    最大联通子数组,这次的题目,我采用的方法为dfs搜索,按照已经取到的数v[][],来进行搜索过程的状态转移,每次对v[][]中标记为1的所有元素依次取其相邻的未被标记为1的元素,将其标记为1,然而,这 ...

  6. UVA 1508 - Equipment 状态压缩 枚举子集 dfs

    UVA 1508 - Equipment 状态压缩 枚举子集 dfs ACM 题目地址:option=com_onlinejudge&Itemid=8&category=457& ...

  7. hihocoder 1334 - Word Construction - [hiho一下第170周][状态压缩+DFS]

    题目链接:https://hihocoder.com/problemset/problem/1334 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given N wo ...

  8. Preparing Olympiad---cf550B(DFS或者状态压缩模板)

    比赛链接:http://codeforces.com/problemset/problem/550/B 给你n个数,选出来只是2个然后求他们的和在L和R的区间内,并且选出来的数中最大值和最小值的差不得 ...

  9. poj 3311 floyd+dfs或状态压缩dp 两种方法

    Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6436   Accepted: 3470 ...

随机推荐

  1. javascript处理HTML的Encode(转码)和解码(Decode)

    HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...

  2. 1.1 Python3基础-前言

    >>返回主目录 Python 交互式代码 Python 脚本式代码 第一段Python代码: print('Hello World!') >>返回主目录

  3. 如何实现一个简易版的 Spring - 如何实现 @Autowired 注解

    前言 本文是 如何实现一个简易版的 Spring 系列第四篇,在 上篇 介绍了 @Component 注解的实现,这篇再来看看在使用 Spring 框架开发中常用的 @Autowired 注入要如何实 ...

  4. 对String Intern()方法的理解

    今天重新看了一点周志明大佬的<深入理解Java虚拟机>,发现这个地方讲的不是很透彻,在网络上看到一些博客基本也都是在搬运原文,搞得一头雾水.弄了半天算是彻底明白了,做一下笔记. 搬运一下原 ...

  5. [unknown source] 快乐树

    一.题目 题目描述 有一棵 \(n\) 个节点的数,每个点有点权 \(a_i\),定义一条路径的权值为路径上所有点的异或和,求所有路径的权值和,有 \(q\) 次修改,每次改一个点的点权. 数据范围 ...

  6. C语言知识汇总,史上最全面总结,没有之一

    C语言基础 C语言学习路线 C语言入门笔记 初识C语言 简单的C程序示例 我们编写的C代码是怎样跑起来的? 简单示例,VS2019调试C语言程序 C语言基础-数据类型 深入理解变量,变量的声明,定义, ...

  7. python graphviz的使用(画图工具)

    参考文章1 参考文章2 一.graphviz安装及配置 graphviz实际上是一个绘图工具,可以根据dot脚本画出树形图等. 1.windows安装 安装graphviz软件:https://gra ...

  8. java例题_05 判断分数等级

    1 /*5 [程序 5 判断分数等级] 2 题目:利用条件运算符的嵌套来完成此题:学习成绩>=90 分的同学用 A 表示,60-89 分之间的用 B 表示,60 分以下的用 C 表示. 3 程序 ...

  9. java例题_01 不死神兔!

    1 /*1 [程序 1 不死神兔] 2 题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 3 程 ...

  10. 计算机体系结构——CH2 指令系统

    CH2 指令系统 右键点击查看图像,查看清晰图像 X-mind CH2 指令系统 数据表示 定义 指计算机硬件能够直接识别,可以被指令系统直接调用的那些数据类型 确定哪些数据类型用哪些数据表示实现,是 ...