斯坦纳树+输出方案
#include<cstdio>
#include<iostream>
#include<cstring>
const int N=210;
const int INF=1e9;
int tot;
int g[N][N];
int mp[N][N];
int val[N];
int mi[N][N];
void flody(){
memset(mi,-1,sizeof(mi));
for(int k=0;k<tot;k++){
for(int i=0;i<tot;i++){
for(int j=0;j<tot;j++){
//g[i][j]=min(g[i][j],g[i][k]+g[k][j]-val[k]);
if(g[i][k]+g[k][j]-val[k]<g[i][j]){
g[i][j]=g[i][k]+g[k][j]-val[k];
mi[i][j]=k;
}
}
}
}
}
int vis[N];
int s[N];
int dp[N][1<<7];
int pre[N][1<<7][2];
int n,m,K;
void stn(){
int cnt=0;
for(int i=0;i<tot;i++){
if(vis[i]){
//printf("%d %d\n",i/m+1,i%m+1);
s[i]=1<<cnt;
cnt++;
}
else s[i]=0;
}
memset(dp,0x3f,sizeof(dp));
for(int i=0;i<tot;i++){
dp[i][s[i]]=val[i];
}
memset(pre,-1,sizeof(pre));
int ed=1<<cnt;
for(int i=1;i<ed;i++){
for(int j=0;j<tot;j++){
for(int k=(i-1)&i;k;k=(k-1)&i){
//dp[j][i]=min(dp[j][i],dp[j][k|s[j]]+dp[j][i^k|s[j]]-val[j]);
int x=dp[j][k|s[j]],y=dp[j][i^k|s[j]];
if(dp[j][i]>x+y-val[j]){
dp[j][i]=x+y-val[j];
pre[j][i][0]=j;
pre[j][i][1]=k|s[j];
}
}
}
for(int j=0;j<tot;j++){
for(int j1=0;j1<tot;j1++){
//dp[j1][i|s[j1]]=min(dp[j1][i|s[j1]],dp[j][i]+val[j1]);
if(dp[j][i]+g[j][j1]-val[j]<dp[j1][i|s[j1]]){
dp[j1][i|s[j1]]=dp[j][i]+g[j][j1]-val[j];
pre[j1][i|s[j1]][0]=j;
pre[j1][i|s[j1]][1]=i;
}
}
}
}
}
int aa[N][N];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int check(int i,int j){
if(i<1||i>n||j<1||j>m)return 0;
return 1;
}
int ans[N][N];
void _find(int x,int y){
int m1=mi[x][y];
ans[x/m+1][x%m+1]=1;
ans[y/m+1][y%m+1]=1;
if(m1!=-1){
_find(x,m1);
_find(m1,y);
}
}
void dfs(int id,int st){
int x=pre[id][st][0],y=pre[id][st][1];
ans[id/m+1][id%m+1]=1;
if(x==-1)return ;
if(x==id){
dfs(x,y|s[id]);
dfs(x,st^y|s[id]);
}
else {
_find(x,id);
dfs(x,y);
}
}
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%d%d%d",&n,&m,&K)!=EOF){
tot=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
mp[i][j]=tot;
scanf("%d",&val[tot++]);
}
}
memset(g,0x3f,sizeof(g));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
g[mp[i][j]][mp[i][j]]=val[mp[i][j]];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<4;k++){
int ii=i+dir[k][0],jj=j+dir[k][1];
if(check(ii,jj)){
g[mp[i][j]][mp[ii][jj]]=val[mp[i][j]]+val[mp[ii][jj]];
}
}
}
}
flody();
// for(int i=0;i<tot;i++){
// for(int j=0;j<tot;j++){
// printf("%d ",g[i][j]);
// }printf("\n");
// }
memset(vis,0,sizeof(vis));
for(int i=0;i<K;i++){
int a,b;scanf("%d%d",&a,&b);
vis[mp[a][b]]=1;
}
stn();
int ed=1<<K;
int id=-1,ans1=INF;
for(int i=0;i<tot;i++){
if(dp[i][ed-1]<ans1){
ans1=dp[i][ed-1];
id=i;
}
}
printf("%d\n",ans1);
memset(ans,0,sizeof(ans));
dfs(id,ed-1);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%c",ans[i][j]?'X':'.');
}printf("\n");
}
}
return 0;
}