[Luogu4294]

题解 : 斯坦纳树

\(dp[i][j]\) 表示以\(i\)号节点为根,当前状态为\(j\)(与\(i\)连通的点为\(1\))

当根\(i\)不改变时状态转移方程是:

\(dp[i][j] = \min_{s \in j}\{dp[i][s] + dp[i][\complement_js] - val[i]\}\)

当根改变时,要求\(i,k\)相邻 :

\(dp[i][j] = \min\{dp[k][j] + val[i]\}\)

记录\(pre[i][now]\)为由哪个状态转移而来,便于输出方案

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} int f[101][1111],a[101],d[4][2]={1,0,0,1,0,-1,-1,0};
bool inq[101],ans[11][11];
pii pre[101][1111];
queue <int> q;
int n,m,K,rt; inline void SPFA(int now){
while(!q.empty()){
int u=q.front();q.pop();inq[u]=0;
for(int i=0;i<4;i++){
int x=u/m,y=u%m,tx=x+d[i][0],ty=y+d[i][1],v=tx*m+ty;
if(tx<0||tx>=n||ty<0||ty>=m) continue;
if(f[u][now]+a[v]<f[v][now]){
f[v][now]=f[u][now]+a[v];
if(!inq[v]) inq[v]=1,q.push(v);
pre[v][now]=pii(u,now);//状态为now定义为与根相连的点的状态,只有相邻的才能转移
}
}
}
} inline void dfs(int x,int y,int now){
int u=x*m+y;
if(!pre[u][now].second) return;
ans[x][y]=1;
if(pre[u][now].first==u) dfs(x,y,now^pre[u][now].second);//如果是由自己更新过来,就要往两个方向回溯
dfs(pre[u][now].first/m,pre[u][now].first%m,pre[u][now].second);//否则就只往一个方向
} int main(){
n=read(),m=read();
memset(f,0x3f,sizeof f);
for(int i=0,now=0;i<n;i++)
for(int j=0;j<m;j++,now++){
a[now]=read();
if(!a[now]) f[now][1<<(K++)]=0,rt=now;
}
for(int now=1;now<(1<<K);now++){
for(int i=0;i<n*m;i++){
for(int s=now&(now-1);s;s=(s-1)&now)
if(f[i][s]+f[i][now^s]-a[i]<f[i][now]){
f[i][now]=f[i][s]+f[i][now^s]-a[i];//用自己的信息更新
pre[i][now]=pii(i,s);
}
if(f[i][now]<f[0][0])
q.push(i),inq[i]=1;
}
SPFA(now);//更新状态为now的全部的值
}
printf("%d\n",f[rt][(1<<K)-1]);
dfs(rt/m,rt%m,(1<<K)-1);
for(int i=0,now=0;i<n;i++){
for(int j=0;j<m;j++,now++){
if(!a[now]) putchar('x');
else putchar(ans[i][j]?'o':'_');
}
putchar('\n');
}
}

[WC2008]游览计划(斯坦纳树)的更多相关文章

  1. 【BZOJ2595】[Wc2008]游览计划 斯坦纳树

    [BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...

  2. Luogu 4294 [WC2008]游览计划 | 斯坦纳树

    题目链接 Luogu 4294 (我做这道题的时候BZOJ全站的SPJ都炸了 提交秒WA 幸好有洛谷) 题解 这道题是[斯坦纳树]的经典例题.斯坦纳树是这样一类问题:带边权无向图上有几个(一般约10个 ...

  3. bzoj2595: [Wc2008]游览计划 斯坦纳树

    斯坦纳树是在一个图中选取某些特定点使其联通(可以选取额外的点),要求花费最小,最小生成树是斯坦纳树的一种特殊情况 我们用dp[i][j]来表示以i为根,和j状态是否和i联通,那么有 转移方程: dp[ ...

  4. BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)

    Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 2030  Solved: 986[Submit][Status][ ...

  5. BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树

    [题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...

  6. bzoj2595 [Wc2008]游览计划——斯坦纳树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...

  7. P4294 [WC2008]游览计划 (斯坦纳树)

    题目链接 差不多是斯坦纳树裸题,不过边权化成了点权,这样在合并两棵子树时需要去掉根结点的权值,防止重复. 题目还要求输出解,只要在转移时记录下路径,然后dfs一遍就好了. #include<bi ...

  8. 洛谷4294 [WC2008]游览计划——斯坦纳树

    题目:https://www.luogu.org/problemnew/show/P4294 大概是状压.两种转移,一个是以同一个点为中心,S由自己的子集拼起来:一个是S相同.中心不同的同层转移. 注 ...

  9. 【BZOJ-2595】游览计划 斯坦纳树

    2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1518  Solved: 7 ...

  10. [WC2008]游览计划 解题报告

    [WC2008]游览计划 斯坦纳树板子题,其实就是状压dp 令\(dp_{i,s}\)表示任意点\(i\)联通关键点集合\(s\)的最小代价 然后有转移 \[ dp_{i,S}=\min_{T\in ...

随机推荐

  1. 【bzoj2705】[SDOI2012]Longge的问题

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2507  Solved: 1531[Submit][ ...

  2. 用gdb+nm调试php c extension程序

    .so写好了是给php脚本调用的,如果php脚本执行崩掉了,.so也只能在进程中饮恨而终,这时候php脚本调试经常用的echo, print_r, var_dump都派不上用场了.即使能打印一点儿错误 ...

  3. js 线程和进程的关系

    进程(process)和线程(thread)是操作系统的基本概念 1.计算机的核心是CPU,它承担了所有的计算任务 2.单个CPU一次只能运行一个任务 3.进程它代表CPU所能处理的单个任务.任一时刻 ...

  4. 单元测试NUnit 的文章

    请参考 https://www.cnblogs.com/ranh941/p/7629279.htmlhttps://blog.csdn.net/qincode/article/details/1831 ...

  5. Position Independent Code (PIC) in shared libraries on x64

    E原文地址:http://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x ...

  6. 解决Spring Boot(2.1.3.RELEASE)整合spring-data-elasticsearch3.1.5.RELEASE报NoNodeAvailableException[None of the configured nodes are available

    Spring Boot(2.1.3.RELEASE)整合spring-data-elasticsearch3.1.5.RELEASE报NoNodeAvailableException[None of ...

  7. Python中多使用迭代器

    英文原文出处:Use More Iterators 本文介绍将代码转换为使用迭代器的原因和实用技巧. 我最喜欢的Python语言的特色之一是生成器,它们是非常有用的,然而当阅读开源代码时,我很少遇到它 ...

  8. fabric Clone

    记录下: var newObj = fabric.util.object.clone(obj); decDoc.dropCanvas.add(newObj., top: }));

  9. 教你如何选择BI数据可视化工具

    本文来自网易云社区. 关于如何选择BI数据可视化工具,总体而言,主流BI产品在选择的时候要除了需要考虑从数据到展现.从公司内到公司外等各种场景,结合前面朋友的回答,还需要考虑以下几点:1:以后的数据处 ...

  10. 「POJ 1741」Tree

    题面: Tree Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define ...