一开始还以为是BFS+DP,最后发现距离是可以直接算的。。。。
然后有一点要注意的是 如果没有g直接输出0......
我用的是状态压缩DP
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define MAX 0x3f3f3f3f
typedef struct{
int x, y;
}Point;
char maps[21][21];
int M, N;
Point point[20];
int point_number;
int distances[20][20];
int dp[1<<16][17];
int calculate_distance( Point p1, Point p2 ){
int a = abs( p1.x - p2.x );
int b = abs( p1.y - p2.y );
return a > b ? a : b;
}
int main(){
int T, Case = 1;
cin >> T;
while( T-- ){
cin >> M >> N;
point_number = 1;
for( int i = 0; i < M; i++ ){
cin >> maps[i];
for( int j = 0; j < N; j++ ){
if( maps[i][j] == 'x' ){
point[0].x = i;
point[0].y = j;
}else if( maps[i][j] == 'g' ){
point[point_number].x = i;
point[point_number++].y = j;
}
}
}
point_number--;
if( point_number == 0 ){// 如果没有g 则直接输出0 注意!
cout << "Case " << Case++ << ": " << 0 << endl;
continue;
}
for( int i = 0; i <= point_number; i++ ){
for( int j = i + 1; j <= point_number; j++ ){
distances[i][j] = distances[j][i] = calculate_distance( point[i], point[j] );
}
}
memset( dp, -1, sizeof( dp ) );
for( int i = 1; i <= point_number; i++ ){
dp[1<<(i-1)][i] = distances[0][i];
}
for( int i = 1; i <= ( 1 << point_number ) - 1; i++ ){
for( int j = 1; j <= point_number; j++ ){
if( ( i & ( 1 << ( j - 1 ) ) ) == 0 ){
continue;
}
for( int k = 1; k <= point_number; k++ ){
if( i & ( 1 << ( k - 1 ) ) ){
continue;
}
if( dp[i|(1<<(k-1))][k] == -1 || dp[i|(1<<(k-1))][k] > dp[i][j] + distances[j][k] ){
dp[i|(1<<(k-1))][k] = dp[i][j] + distances[j][k];
}
}
}
}
int ans = MAX;
for( int i = 1; i <= point_number; i++ ){
ans = min( ans, dp[(1<<point_number)-1][i] + distances[i][0] );
}
cout << "Case " << Case++ << ": " << ans << endl;
}
return 0;
}