luoguP4294 [WC2008]游览计划
2024-10-19 01:18:41
题意
斯坦纳树裸题。
显然答案是棵树。
设\(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;
}
最新文章
- java学习笔记之数组
- su,exit,adduser,deluser,usermod,groups
- 在ubuntu 14.04 64位系统上安装32位库
- 根据中国气象局提供的API接口实现天气查询
- 如何在hadoop中控制map的个数
- ssh 应用
- android大牛高焕堂最新力作-android架构师之路
- 让盘古分词支持最新的Lucene.Net 3.0.3
- jg-table 过程2 ( jgTable )
- iwebshop插件的操作
- AutoAudit研究学习
- Flask-信号(blinker)
- text-decoration、text-decoration-color、text-decoration-line、text-decoration-style属性
- Alpha 冲刺 (3/10)
- 使用 universalimageloader 缓存图片的配置类及使用方法
- Python3学习笔记23-StringIO和BytesIO
- unity3d生命周期
- QT文件(夹)操作---QFile、QDir、QFileInfo、QTextStream和QDataStream异同
- DataContractSerializer数据不一致下序列化
- P3119 [USACO15JAN]草鉴定Grass Cownoisseur
热门文章
- 提高python运行效率-numba
- [PHP] 再续 Laravel 5.5 接口 跨域问题 【终极暴力解决办法】
- MySQL实战45讲学习笔记:第二十七讲
- JDK的小Bug你了解么?
- Mybatis中的association用法
- 【LOJ#3146】[APIO2019]路灯(树套树)
- SATA接口、PCI/PCIe、NVMe的介绍
- Spring源码系列 — 容器Extend Point(一)
- CentOS6 + MapServer7.4编译
- Java生鲜电商平台-redis缓存在商品中的设计与架构