http://www.2cto.com/kf/201308/236512.html
http://blog.csdn.net/catalyst1314/article/details/19008903
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
int n,m,k;
int map[220][220];
int f[220][220];
int h[20][2];
int vis[220][220];
int dist[20][20];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int dp[1<<15][15];
struct node
{
int x,y,dis;
bool operator < (const node &a) const
{
return a.dis < dis;
}
};
bool com(int a,int b)
{
if(a>=1&&b>=1&&a<=n&&b<=m)
return true;
return false;
}
void bfs(int x,int y)
{
int s=f[x][y];
priority_queue<node> q;
int v[20]={0};
v[s]=1;
node ans;
ans.x=x;
ans.y=y;
ans.dis=0;
q.push(ans);
memset(vis,0,sizeof(vis));
vis[x][y]=1;
int tot=1;
while(!q.empty())
{
node sta=q.top();
node next;
q.pop();
if(!v[0]&&(sta.x==1||sta.x==n||sta.y==1||sta.y==m))
{
v[0]=1;
tot++;
dist[s][0]=sta.dis;
dist[0][s]=sta.dis+map[x][y];
if(tot==k+1) return ;
}
int id=f[sta.x][sta.y];
if(id!=0&&!v[id])
{
v[id]=1;
tot++;
dist[s][id]=sta.dis;
if(tot==k+1) return ;
}
int i;
for(i=0;i<4;i++)
{
next.x=sta.x+dir[i][0];
next.y=sta.y+dir[i][1];
next.dis=sta.dis+map[next.x][next.y];
if(com(next.x,next.y)&&vis[next.x][next.y]==0&&map[next.x][next.y]!=-1)
{
vis[next.x][next.y]=1;
q.push(next);
}
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(f,0,sizeof(f));
memset(dist,0,sizeof(dist));
memset(h,0,sizeof(h));
int i,j;
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&map[i][j]);
cin>>k;
for(i=1;i<=k;i++){
scanf("%d%d",&h[i][0],&h[i][1]);
h[i][0]++,h[i][1]++;
f[h[i][0]][h[i][1]]=i;
}
for(i=1;i<=k;i++)
bfs(h[i][0],h[i][1]);
if(k==0) {printf("0\n"); continue;}
memset(dp,inf,sizeof(dp));
for(i=0;i<=k;i++)
dp[1<<i][i]=dist[0][i];
int end=(1<<(k+1));
int b;
for(i=0;i<end;i++)
for(j=0;j<=k;j++)
if((i>>j)&1){
for(b=0;b<=k;b++){
if((i>>b)&1)
dp[i][j]=min(dp[i][j],dp[i-(1<<j)][b]+dist[b][j]);
}
}
printf("%d\n",dp[end-1][0]);
}
}