题意

斯坦纳树裸题。

显然答案是棵树。

设\(f[i][s]\)表示以\(i\)为根,集合为\(s\)的最小代价。

先在同根之间转移:

\(f[i][s]=min(f[i][t]+f[i][s\ xor\ t]-val[i])\)

减\(val[i]\)是因为算了两遍。

之后扩展新点:

\(f[i][s]=min(f[j][s]+val[i]),(i,j)\)联通,这个可以用\(spfa\)。

code:

#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define mkp make_pair
#define fir first
#define sec second
const int maxn=12;
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
int n,m,K,tot,root,ans=0x3f3f3f3f;
int id[maxn][maxn],a[maxn][maxn],f[maxn*maxn][1<<maxn];
pii pos[maxn*maxn],g[maxn*maxn][1<<maxn];
bool vis[maxn*maxn];
bool check[maxn][maxn];
vector<int>keypoints;
queue<int>q;
inline void spfa(int s)
{
while(!q.empty())
{
int x=q.front();q.pop();vis[x]=0;
for(int i=0;i<4;i++)
{
int mx=pos[x].fir+dx[i],my=pos[x].sec+dy[i];
if(mx<1||mx>n||my<1||my>m)continue;
int y=id[mx][my];
if(f[y][s]>f[x][s]+a[pos[y].fir][pos[y].sec])
{
f[y][s]=f[x][s]+a[pos[y].fir][pos[y].sec];
if(!vis[y])vis[y]=1,q.push(y);
g[y][s]=mkp(x,s);
}
}
}
}
void dfs(int now,int s)
{
if(!g[now][s].sec)return;
check[pos[now].fir][pos[now].sec]=1;
if(g[now][s].fir==now)dfs(now,s^g[now][s].sec);
dfs(g[now][s].fir,g[now][s].sec);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]),id[i][j]=++tot,pos[tot]=mkp(i,j);
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!a[i][j])f[id[i][j]][1<<K]=0,K++,keypoints.push_back(id[i][j]);
for(int s=1;s<(1<<K);s++)
{
for(int i=1;i<=n*m;i++)
{
for(int t=s&(s-1);t;t=(t-1)&s)
if(f[i][s]>f[i][s^t]+f[i][t]-a[pos[i].fir][pos[i].sec])
{
f[i][s]=f[i][s^t]+f[i][t]-a[pos[i].fir][pos[i].sec];
g[i][s]=mkp(i,t);
}
if(f[i][s]<0x3f3f3f3f)q.push(i),vis[i]=1;
}
spfa(s);
}
for(unsigned int i=0;i<keypoints.size();i++)
if(ans>f[keypoints[i]][(1<<K)-1])ans=f[keypoints[i]][(1<<K)-1],root=keypoints[i];
printf("%d\n",ans);
dfs(root,(1<<K)-1);
for(int i=1;i<=n;i++,puts(""))
for(int j=1;j<=m;j++)
if(!a[i][j])putchar('x');
else putchar(check[i][j]?'o':'_');
return 0;
}

最新文章

  1. java学习笔记之数组
  2. su,exit,adduser,deluser,usermod,groups
  3. 在ubuntu 14.04 64位系统上安装32位库
  4. 根据中国气象局提供的API接口实现天气查询
  5. 如何在hadoop中控制map的个数
  6. ssh 应用
  7. android大牛高焕堂最新力作-android架构师之路
  8. 让盘古分词支持最新的Lucene.Net 3.0.3
  9. jg-table 过程2 ( jgTable )
  10. iwebshop插件的操作
  11. AutoAudit研究学习
  12. Flask-信号(blinker)
  13. text-decoration、text-decoration-color、text-decoration-line、text-decoration-style属性
  14. Alpha 冲刺 (3/10)
  15. 使用 universalimageloader 缓存图片的配置类及使用方法
  16. Python3学习笔记23-StringIO和BytesIO
  17. unity3d生命周期
  18. QT文件(夹)操作---QFile、QDir、QFileInfo、QTextStream和QDataStream异同
  19. DataContractSerializer数据不一致下序列化
  20. P3119 [USACO15JAN]草鉴定Grass Cownoisseur

热门文章

  1. 提高python运行效率-numba
  2. [PHP] 再续 Laravel 5.5 接口 跨域问题 【终极暴力解决办法】
  3. MySQL实战45讲学习笔记:第二十七讲
  4. JDK的小Bug你了解么?
  5. Mybatis中的association用法
  6. 【LOJ#3146】[APIO2019]路灯(树套树)
  7. SATA接口、PCI/PCIe、NVMe的介绍
  8. Spring源码系列 — 容器Extend Point(一)
  9. CentOS6 + MapServer7.4编译
  10. Java生鲜电商平台-redis缓存在商品中的设计与架构