Problem K. 找宝箱
Time Limit: 2000ms Memory Limit: 65536kb
Description
作为一个强迫症患者,小 Y 在走游戏里的迷宫时一定要把所有的宝箱收集齐才肯罢休。
现在给你一个 N M 的迷宫,里面有障碍、空地和宝箱,小 Y 在某个起始点,每一步小 Y 可以往上下左
右走,当然前提时没有走出迷宫并且走到的点不是障碍。如果小 Y 走到了某个为宝箱的点,那么这个宝箱就被
他收集到了,然后此处变为空地。
现在你需要计算小 Y 最少需要走多少步才能收集齐所有的宝箱。
Input
输入包含多组数据。
对于每组数据,第一行两个正整数 N;M (1 N;M 100),表示迷宫大小。
接下来 N 行,每行 M 个整数,第 i + 1 行的第 j 个整数表示迷宫第 i 行第 j 列的情况,0 表示空地, 1
表示障碍,1 表示宝箱,2 表示小 Y 的起始点。保证 2 只有一个,且宝箱数量不超过 5 个。
数据以两个 0 表示结尾。
Output
对于每组数据输出一行,包含一个整数,表示小 Y 最少的步数。如果小 Y 无法收集齐所有宝箱,输出
1。
Sample
INPUT OUTPUT
3 5
1 -1 1 -1 2
0 -1 0 -1 0
0 0 0 0 0
0 0
12
分析:
宝藏数量很少, 可以先用BFS, 搜索出各宝藏,起点之间距离,然后构图,在新图上DFS搜索
出最短路径。。。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<map> #include<queue> #include<math.h> using namespace std; const int inf = 0x7f7f7f7f; int mp[110][110]; int G[120][120]; int visit[120][120]; int gg[120][120]; int hash[110]; int start, end, steps, sum, maxn, bao, m_bao, tt; int xx[ ] = {-1, 0, 0, 1}; int yy[ ] = {0, 1, -1, 0}; int N,M; struct node { int x, y,step; }; int jugde( int x, int y) { if( x < 1 || x > N || y < 1 || y > M ) return 0; return 1; } void bfs( ) { queue<node>q; memset(visit, 0, sizeof(visit)); node p; p.x = start; p.y = end; p.step = 0; q.push( p ); while( !q.empty() ) { node px = q.front( ); q.pop( ); int x = px.x; int y = px.y; visit[x][y] = 1; int dis = px.step; if( mp[x][y] == 1 || mp[x][y] == 2) { G[gg[start][end]] [gg[x][y]] = dis; } for( int i = 0; i < 4; i++) { int x1 = xx[i] + x; int y1 = yy[i] + y; if( mp[x1][y1] != -1 && jugde(x1, y1) && !visit[x1][y1] ) { node py; py.x = x1; py.y = y1; py.step = dis + 1; visit[x1][y1] = 1; q.push( py ); } } } } void DFS(int x, int m, int s) { for( int i = 1; i <= tt; i++) if( G[x][i] != inf && G[x][i] != 0 && !hash[i]) { if( m + 1 == m_bao ) { bao = min( bao, s + G[x][i]); } hash[x] = 1; DFS( i , m + 1, s + G[x][i]); hash[x] = 0; } } int main( ) { while( scanf("%d%d", &N, &M), N + M) { tt=0; steps = 0; sum = 0; maxn = max( N, M ); bao = inf; m_bao = 0; int p, q; memset(hash, 0, sizeof(hash)); for( int i = 1; i <= 110; i++) for(int j = 1; j <= 110; j++) G[i][j] = ( i == j ) ? 0 : inf; for( int i = 1; i <= N; i++) for( int j = 1; j <= M; j++) { scanf("%d",&mp[i][j]); if( mp[i][j] == 1 ) { m_bao++; gg[i][j] = ++tt; } if( mp[i][j] == 2 ) { p = i; q = j; gg[i][j] = ++tt; } } for( int i = 1;i <= N; i++) for( int j = 1; j <= M; j++) { if( mp[i][j] == 2 || mp[i][j] == 1 ) { start = i; end = j; bfs( ); } } DFS(gg[p][q], 0, 0); if( bao == inf ) puts("-1"); else printf("%d\n",bao); } return 0; }