D - 小明的迷宫
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d
& %I64u
Description
小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫。因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷宫。
Input
有多组测试数据。
每组数据第一行给出两个正整数n,m(0<n,m<=100)。代表迷宫的长和宽。
接着n行,每行m个整数。正数代表财宝(财宝的个数不超过10);负数代表墙,无法通过;0代表通道。
每次移动到相邻的格子,所花费的时间是1秒。小明只能按上、下、左、右四个方向移动。
小明的初始位置是(1,1)。迷宫的出口也在(1,1)。
Output
输出获得所有财宝并逃出迷宫所花费的最小时间,如果无法完成目标则输出-1。
Sample Input
3 30 0 00 100 00 0 02 21 11 1
Sample Output
44
求解旅行商(TSP)问题,一般有三个方法,dp,或者回溯或者什么分之限界啥啥的,不太懂,参考了下别人的方法,其他的方法以后再说,回溯的方法是,先求出各个宝藏(加上起点)间的最短路,因为最多10个宝藏,再用次DFS回溯更新出从起点开始遍历过且仅遍历一次的最小路径。
代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<cmath> #include<queue> #include<vector> #include<map> #include<set> #define INF 0x3f3f3f3f #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int maxd=100+5; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1 | 1 typedef long long ll; typedef pair<int,int> pii; //--------------------------- int dx[]= {0,0,1,-1}; int dy[]= {1,-1,0,0}; typedef struct node { int x,y,t; node(int x_ = 0, int y_ = 0, int t_ = 0) { x = x_; y = y_; t = t_; } }; int mz[maxd][maxd],vis[maxd][maxd]= {0},path[20][20]; int vist[20]; int cnt,ans,n,m; vector<node> gold; void init() { cnt=0; ans=INF; gold.clear(); node tmp(1,1,0); gold.push_back(tmp); for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) { scanf("%d",&mz[i][j]); if(mz[i][j]>0 && !(i==1 && j==1)) { ++cnt; node tmp(i,j,0); gold.push_back(tmp); } } //cout<<"gold="<<gold.size()<<endl; cnt=gold.size(); for(int i=0; i<cnt; ++i) for(int j=0; j<cnt; ++j) path[i][j]=0; } bool ok(int x,int y) { if(x<=0 || y<=0 || x>n || y>m) return false; return true; } int bfs(node a,node b) { vis[a.x][a.y]=1; queue<node> q; q.push(a); while(!q.empty()) { node now=q.front(); q.pop(); if(now.x==b.x && now.y==b.y) { return now.t; } for(int i=0; i<4; ++i) { int xx=now.x+dx[i]; int yy=now.y+dy[i]; int tt=now.t+1; if(ok(xx,yy) && vis[xx][yy]==0 && mz[xx][yy]>=0) { vis[xx][yy]=1; node tmp(xx,yy,tt); q.push(tmp); } } } return -1; } void dfs(int x,int tmpcnt,int t) { if(t>ans) return; if(tmpcnt==cnt && path[x][0]!=-1) { ans=min(ans,t+path[x][0]); return; } for(int i=0; i<cnt; ++i) { //cout<<i<<endl; if(vist[i]==0 && path[x][i]!=-1) { vist[i]=1; // cout<<"vist1="<<i<<endl; dfs(i,tmpcnt+1,path[x][i]+t); // cout<<"vist2="<<i<<endl; vist[i]=0; } } } int main() { freopen("1.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF) { init(); for(int i=0; i<cnt; ++i) for(int j=i+1; j<cnt; ++j) { mem(vis,0); path[i][j]=path[j][i]=bfs(gold[i],gold[j]); } // for(int i=0; i<cnt; ++i) // for(int j=i+1; j<cnt; ++j) // cout<<i<<' '<<j<<' '<<path[i][j]<<endl; // cout<<endl; mem(vist,0); dfs(0,0,0); if(mz[1][1]<0) {printf("-1\n");continue;} if(ans==INF) printf("-1\n"); else printf("%d\n",ans); } return 0; }
时间: 2024-10-27 08:21:14