这个其实就是状压DP+spfa.
本题需要输出方案,有一点点麻烦
code:
#include <bits/stdc++.h>
#define ll long long
#define N 12
#define inf 0x3f3f3f3f
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
int n,m,K=0,tot;
int val[N][N];
int bin[N],f[N*N][1<<N],id[N][N],X[N*N],Y[N*N],v[N*N],inq[N*N];
struct node
{
int pos,s;
node(int pos=0,int s=0):pos(pos),s(s){}
}pre[N*N][1<<N];
queue<int>q;
void solve(int cur)
{
while(!q.empty())
{
int u=q.front();
q.pop(),inq[u]=0;
int x=X[u],y=Y[u];
for(int i=0;i<4;++i)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(!(xx>=1&&xx<=n&&yy>=1&&yy<=m))
continue;
int to=id[xx][yy];
if(f[to][cur]>f[u][cur]+v[to])
{
f[to][cur]=f[u][cur]+v[to];
pre[to][cur]=node(u,cur);
if(!inq[to])
{
inq[to]=1;
q.push(to);
}
}
}
}
}
int mk[N][N];
void dfs(int x,int now)
{
mk[X[x]][Y[x]]=1;
if(!pre[x][now].pos)
return;
if(pre[x][now].pos==x)
dfs(x,now^pre[x][now].s);
dfs(pre[x][now].pos,pre[x][now].s);
}
int main()
{
// setIO("input");
int i,j,rr=0;
scanf("%d%d",&n,&m);
for(i=1;i<N;++i)
bin[i]=1<<(i-1);
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
id[i][j]=++tot,X[id[i][j]]=i,Y[id[i][j]]=j;
memset(f,0x3f,sizeof(f));
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
{
scanf("%d",&val[i][j]);
v[id[i][j]]=val[i][j];
if(!val[i][j])
{
++K;
rr=id[i][j];
f[id[i][j]][bin[K]]=0;
}
}
for(i=1;i<bin[K+1];++i)
{
for(int pos=1;pos<=tot;++pos)
{
for(j=i&(i-1);j;j=i&(j-1))
{
if(f[pos][j]+f[pos][i^j]-v[pos]<f[pos][i])
{
f[pos][i]=f[pos][j]+f[pos][i^j]-v[pos];
pre[pos][i]=node(pos,j);
}
}
if(f[pos][i]<inf)
{
inq[pos]=1;
q.push(pos);
}
}
solve(i);
}
printf("%d
",f[rr][bin[K+1]-1]);
dfs(rr,bin[K+1]-1);
for(i=1;i<=n;++i)
{
for(j=1;j<=m;++j)
{
if(!val[i][j])
{
printf("x");
}
else
{
if(mk[i][j]) printf("o");
else printf("_");
}
}
printf("
");
}
return 0;
}