记得考虑答案为0的情况。。。。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 1000005
#define maxm 2000005
#define eps 1e-10
#define mod 1000000007
#define INF 1e9
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
int dp[4000][20];
int g[20][20];
int dist[20];
int p[20];
int n, m, cnt;
inline int calc(int i, int j)
{
return i * m + j;
}
void read(void)
{
int x;
cnt = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
scanf("%d", &x);
if(x > 0) p[cnt++] = calc(i, j);
}
for(int i = 0; i < cnt; i++) {
int x = p[i] / m;
int y = p[i] % m;
dist[i] = x + y;
//printf("DDDDDDD %d %d %d\n", x, y, i);
for(int j = 0; j < cnt; j++) {
int x1 = p[j] / m;
int y1 = p[j] % m;
g[i][j] = abs(x1 - x) + abs(y1 - y);
}
}
//for(int i = 1; i <= cnt; i++) printf("BBBBBB %d\n", dist[i]);
//for(int i = 0; i < cnt; i++)
// for(int j = 0; j < cnt; j++)
// printf("AA %d\n", g[i][j]);
}
void work(void)
{
if(cnt == 0) {
printf("0\n");
return;
}
for(int i = 0; i < (1 << cnt); i++)
for(int j = 0; j < cnt; j++)
dp[i][j] = INF;
for(int i = 0; i < cnt; i++) dp[1 << i][i] = dist[i];
//for(int j = 0; j < cnt; j++)
for(int i = 0; i < (1 << cnt); i++)
for(int j = 0; j < cnt; j++) {
if(dp[i][j] == INF) continue;
//printf("AA %d %d %d\n", i, j, dp[i][j]);
for(int k = 0; k < cnt; k++) {
if((i & (1 << k)) == 0) dp[i | (1 << k)][k] = min(dp[i | (1 << k)][k], dp[i][j] + g[j][k]);
}
}
int ans = INF;
for(int i = 0; i < cnt; i++) ans = min(ans, dp[(1 << cnt) - 1][i] + dist[i]);
printf("%d\n", ans);
}
int main(void)
{
while(scanf("%d%d", &n, &m)!=EOF) {
read();
work();
}
return 0;
}