bjtu 1846. Infinity的装备[状压dp+dfs/bfs]

https://citel.bjtu.edu.cn/acm/oj/problem/1846

1846. Infinity的装备

时间限制 1000 ms
内存限制 64 MB

题目描述

“测试服终于下完了!” Infinity 来到了一望无际的沙漠 Miramar。

Infinity 降落到了 Los Leones 城,他在天上看到城区里有一些装备。

但是城区地形复杂、装备繁多,来回捡各种装备肯定要走不少回头路。

Infinity 想尽快搜齐所有装备,你能告诉他最快多久可以集齐所有装备吗?

Los Leones 城可以表示为一个 n×m

的矩形。

其中,

# 表示不可穿越的高墙,I 表示 Infinity 降落的位置,E 表示装备。

Infinity 一次移动可以向上下左右之一的方向移动一格,但不能到达高墙。

当 Infinity 和装备处于同一位置时,Infinity 可以(不消耗移动步数地)立即获得这个装备。

输入数据

第一行为一个整数 t (1t200)

,表示数据的组数。接下来对于每组数据:

第一行为三个整数 n,m,k (3n,m10;1k10)

,表示城市的高、宽,和装备的数量。

接下来 n

行,每行为一个长度为 m

的字符串,表示城市的布局,具体含义见题目描述。

保证城市的最外圈都是高墙。保证所有装备从初始位置可达。

输出数据

对于每组数据,输出一行:

第一行为一个整数,表示 Infinity 集齐所有装备所需最少的移动次数。

样例输入

 
1
5 7 2
#######
#   I #
# ### #
# E#E #
#######

样例输出

 
14

样例说明

测试数据有点小问题,迷之 WA / RE / TLE 可以看一下这个链接。

http://blog.csdn.net/qwb492859377/article/details/48323443

[分析]:状压dp+dfs /网上搜一下这个有蛮多类似的题目.

[代码]:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define pb push_back
#define fi first
#define se second
#define ll long long
#define sz(x) (int)(x).size()
char a[20][20];
int id[20][20];
struct node{
    int r,c;
};
int dp[1<<10][10];
int sd[11];
int ed[11][11];
vector<node> e;
int tmpd[12][12];
bool safe_gets(char *S){  
    int n = strlen(S);  
    if(!gets(S)) return false;  
    if(n && S[n - 1] =='\r') S[n - 1] = 0;  
    return true;  
}
int Lowbit(int x){
  return x&(-x);
}
int xx[100000];
int main(){
    int tmp=1;
    for(int i=0;i<10;i++){
        xx[tmp]=i;
        tmp*=2;
    }
    int t;
    scanf("%d",&t);
    while(t--){
        e.clear();
        node s;
        int n,m,k;
        scanf("%d %d %d",&n,&m,&k);
        getchar();
        getchar();
        for(int i=1;i<=n;i++){
            safe_gets(a[i]+1);
            for(int j=1;j<=m;j++){
                if(a[i][j]=='E'){
                    id[i][j]=sz(e);
                    e.pb({i,j});
                }else if(a[i][j]=='I'){
                    s={i,j};
                }
            }
        }
        if(sz(e)!=k)return 1;
        memset(tmpd,127,sizeof(tmpd));
        tmpd[s.r][s.c]=0;
        queue<pair<int,int>> q;
        q.push({s.r,s.c});
        while(q.size()){
            int r=q.front().fi,c=q.front().se;
            if(a[r][c]=='E'){
                sd[id[r][c]]=tmpd[r][c];
            }
            q.pop();
            if(a[r+1][c]!='#' && tmpd[r+1][c]==tmpd[0][0]){
                tmpd[r+1][c]=tmpd[r][c]+1;
                q.push({r+1,c});
            }
            if(a[r][c+1]!='#' && tmpd[r][c+1]==tmpd[0][0]){
                tmpd[r][c+1]=tmpd[r][c]+1;
                q.push({r,c+1});
            }
            if(a[r-1][c]!='#' && tmpd[r-1][c]==tmpd[0][0]){
                tmpd[r-1][c]=tmpd[r][c]+1;
                q.push({r-1,c});
            }
            if(a[r][c-1]!='#' && tmpd[r][c-1]==tmpd[0][0]){
                tmpd[r][c-1]=tmpd[r][c]+1;
                q.push({r,c-1});
            }
        }
        for(int i=0;i<sz(e);i++){
            memset(tmpd,127,sizeof(tmpd));
            tmpd[e[i].r][e[i].c]=0;
            q.push({e[i].r,e[i].c});
            while(q.size()){
                int r=q.front().fi,c=q.front().se;
                if(a[r][c]=='E'){
                    ed[i][id[r][c]]=tmpd[r][c];
                }
                q.pop();
                if(a[r+1][c]!='#' && tmpd[r+1][c]==tmpd[0][0]){
                    tmpd[r+1][c]=tmpd[r][c]+1;
                    q.push({r+1,c});
                }
                if(a[r][c+1]!='#' && tmpd[r][c+1]==tmpd[0][0]){
                    tmpd[r][c+1]=tmpd[r][c]+1;
                    q.push({r,c+1});
                }
                if(a[r-1][c]!='#' && tmpd[r-1][c]==tmpd[0][0]){
                    tmpd[r-1][c]=tmpd[r][c]+1;
                    q.push({r-1,c});
                }
                if(a[r][c-1]!='#' && tmpd[r][c-1]==tmpd[0][0]){
                    tmpd[r][c-1]=tmpd[r][c]+1;
                    q.push({r,c-1});
                }
            }
        }
        int res=1e9;
        memset(dp,127,sizeof(dp));
        for(int i=0;i<k;i++){
            dp[1<<i][i]=sd[i];
            if(k==1)res=sd[i];
        }
        int up=(1<<k);
        for(int j=1;j<=k;j++){
            for(int mask = (1<<j)-1;mask<up;){
                vector<int> out,in;
                for(int i=0;i<k;i++){
                    if(mask&(1<<i)){
                        in.pb(i);
                    }
                    else out.pb(i);
                }
                for(int i=0;i<sz(in);i++){
                    for(int j=0;j<sz(out);j++){
                        dp[mask|(1<<out[j])][out[j]]=min(dp[mask|(1<<out[j])][out[j]],dp[mask][in[i]]+ed[in[i]][out[j]]);
                    }
                }
                int tmp=mask & -mask;
                mask = (mask + tmp) | (((mask^(mask+tmp))>>2)/tmp);
            }
        }
        for(int i=0;i<k;i++)res=min(dp[up-1][i],res);
        printf("%d\n",res);
    }
    return 0;
}
View Code

 

posted @ 2018-03-03 12:44  Roni_i  阅读(330)  评论(0编辑  收藏  举报