FZU 2186 小明的迷宫 (TSP)

题意给出一个迷宫,然后拿到所有宝藏然后回到原点,求最短时间。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef long long ll;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
const int oo=0x3f3f3f3f;
const int MOD=1000000007;
const int maxn=105;
int dis[12][12];
int maze[maxn][maxn],mark[maxn][maxn];
int step[maxn][maxn];
int id[maxn][maxn];
int n,m,cnt;
struct Node{
    int x,y;
    Node(){}
    Node(int x_,int y_){
        x=x_;y=y_;
    }
}q[maxn*maxn],node[12];
int f,r;
int dp[B(11)+5][12];

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

void BFS(int sx,int sy){
    memset(step,0x3f,sizeof step);
    memset(mark,0,sizeof mark);
    int a=id[sx][sy],b;
    step[sx][sy]=0;
    Node now,next;
    now=Node(sx,sy);
    f=r=0;
    q[r++]=now;
    while(f<r){
        now=q[f++];
        b=id[now.x][now.y];
        if(b>=0)
            cmin(dis[a][b],step[now.x][now.y]);
        for(int i=0;i<4;i++){
            next.x=now.x+d[i][0];
            next.y=now.y+d[i][1];
            if(next.x>=1&&next.x<=n&&next.y>=1&&next.y<=m){
                if(maze[next.x][next.y]>=0&&!mark[next.x][next.y]){
                    if(step[next.x][next.y]>step[now.x][now.y]+1){
                        step[next.x][next.y]=step[now.x][now.y]+1;
                        mark[next.x][next.y]=1;
                        q[r++]=next;
                    }
                }
            }
        }
    }
}

void Input(){
    memset(dp,0x3f,sizeof dp);
    memset(dis,0x3f,sizeof dis);
    cnt=0;
    node[cnt]=Node(1,1);
    id[1][1]=cnt++;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&maze[i][j]);
            if(i==1&&j==1)continue;
            if(maze[i][j]>0){
                id[i][j]=cnt;
                node[cnt]=Node(i,j);
                cnt++;
            }
            else id[i][j]=-1;
        }
}

void DP(){
    for(int i=0;i<cnt;i++)BFS(node[i].x,node[i].y);
    int full=B(cnt)-1;
    dp[1][0]=0;
    for(int s=0;s<=full;s++){
        for(int i=0;i<cnt;i++){
            if(dp[s][i]==oo)continue;
            if(!(s&B(i)))continue;
            for(int j=0;j<cnt;j++){
                if(i==j)continue;
                int st=s|B(j);
                cmin(dp[st][j],dp[s][i]+dis[i][j]);
            }
        }
    }
    if(dp[full][0]==oo)dp[full][0]=-1;
    printf("%d\n",dp[full][0]);
}

int main(){
    //freopen("E:\\read.txt","r",stdin);
    while(scanf("%d %d",&n,&m)!=EOF){
        Input();
        DP();
    }
	return 0;
}
/**
5 5
 0  0  0  0  0
-1 -1 -1 -1  0
 1  1  1  1  0
 2 -1  1 -1  0
 3  2  1  1  0
*/





你可能感兴趣的:(FZU 2186 小明的迷宫 (TSP))