炸老师与他的女朋友们 bfs+状压

炸老师与他的女朋友们

Description

 

qdu最帅的炸老师今天又要抽空去找他的女朋友们了,但是考虑到他的好gay友ycb仍是个单身狗,炸老师作为基友不希望打击他。所以他在找女朋友们的路途中必须要避开ycb老师,可他又不知道ycb的具体位置,只知道一些可能的位置,所以他必须要避开所有这些位置,同时炸老师希望找完所有女朋友所用的时间最短,因为炸老师很忙的。

现在假定炸老师在一个n*m的矩阵中,'S'为炸老师的初始位置,'.'表示可以走,'#'表示ycb老师的可能位置,'*'表示炸老师所有女朋友的位置,炸老师每走一格需要花费一秒的时间,而且炸老师每次只能往上下左右四个方向走,请你帮炸老师计算一下他找完所有女朋友所需的最短时间(找完最后一个女朋友即可,无需回到出发点),由于炸老师非常特别无敌快,因此可以不考虑炸老师在女友家停留的时间。如果炸老师没有办法在避开ycb所有可能位置的条件下找完他的女朋友们,那么炸老师就不去了。

Input

输入包含多组测试样例 第一行输入两个整数n,m表示n行m列的矩阵(0<n,m<=30) 第二行到n+1行每行m个字符,含义如上题所述。(输入保证*的个数不会超过10个,毕竟炸老师的精力也是有限的)

Output

对于每组输出,输出只包含一个整数。如果炸老师可以找完他的女朋友们,则输出最短时间,如果炸老师不去了,那么输出-1.

Sample Input 1 

扫描二维码关注公众号,回复: 58677 查看本文章
7 13
*...........*
....#...#....
..#...#..#...
..#......#...
...#.S..#....
....#.#......
*....#......*

Sample Output 1

33

Sample Input 2 

10 10
..........
..S.......
..........
..........
..........
.....#####
.....#....
.....#.*..
.....#....
.....#....

Sample Output 2

-1

Sample Input 3 

3 7
.S...*.
.......
.*...*.

Sample Output 3

8

Hint

1.jpg

2.png

3.png

Source

六一八杯青岛大学首届编程大赛个人赛暨ACM集训队16级纳新

回顾acm纳新。小数据,一道经典的状压题。因为部分路径能够重复走,所以这里的b[x][y][sta]数组需要标记状态,sta每一位表示每个女朋友是否被访问到。只有在(x,y)走过且当前状态被标记过时,该点才不会继续加入队列。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<algorithm>
#define MAX 35
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;

char a[MAX][MAX];
int b[MAX][MAX][(1<<11)+5],bb[MAX][MAX];
int t[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct Node{
    int x,y,sta,s;
}node;
queue<Node> q;
int main()
{
    int n,m,c,bx,by,i,j;
    while(~scanf("%d%d",&n,&m)){
        c=0;
        memset(bb,0,sizeof(bb));
        for(i=0;i<n;i++){
            scanf(" %s",a[i]);
            for(j=0;j<m;j++){
                if(a[i][j]=='*'){
                    bb[i][j]=c;
                    c++;
                }
                else if(a[i][j]=='S'){
                    bx=i;
                    by=j;
                }
            }
        }
        memset(b,0,sizeof(b));
        while(q.size()){
            q.pop();
        }
        node.x=bx;
        node.y=by;
        node.sta=0;
        node.s=0;
        b[bx][by][0]=1;
        q.push(node);
        int f=-1;
        while(q.size()){
            for(i=0;i<4;i++){
                int tx=q.front().x+t[i][0];
                int ty=q.front().y+t[i][1];
                int sta=q.front().sta;
                int ss=q.front().s;
                if(tx<0||ty<0||tx>=n||ty>=m) continue;
                if(a[tx][ty]=='#') continue;
                if(a[tx][ty]=='*') sta|=1<<bb[tx][ty];
                if(b[tx][ty][sta]==1) continue;
                b[tx][ty][sta]=1;
                if(sta==(1<<c)-1){
                    f=ss+1;
                    break;
                }
                node.x=tx;
                node.y=ty;
                node.sta=sta;
                node.s=ss+1;
                q.push(node);
            }
            q.pop();
            if(f>-1) break;
        }
        if(f==-1) printf("-1\n");
        else printf("%d\n",f);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/yzm10/p/8931968.html