【题目分析】

斯坦纳树=子集DP+SPFA?

用来学习斯坦纳树的模板。

大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态。

更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即可。

【代码】

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cmath>
  5.  
  6. #include <set>
  7. #include <map>
  8. #include <string>
  9. #include <algorithm>
  10. #include <vector>
  11. #include <iostream>
  12. #include <queue>
  13.  
  14. using namespace std;
  15.  
  16. #define maxn 11
  17. #define F(i,j,k) for (int i=j;i<=k;++i)
  18. #define inf (0x3f3f3f3f)
  19.  
  20. int Getint()
  21. {
  22. int x=0,f=1; char ch=getchar();
  23. while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
  24. while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
  25. return x*f;
  26. }
  27.  
  28. int n,m,a[maxn][maxn],cnt=0,dp[maxn][maxn][1<<maxn],pre[maxn][maxn][1<<maxn][4];
  29. queue <int> qi,qj;
  30. int inq[maxn][maxn],b[maxn][maxn];
  31. int mov[4][2]={0,1,1,0,-1,0,0,-1};
  32.  
  33. void dfs(int x,int y,int k)
  34. {
  35. // cout<<"dfs "<<x<<" "<<y<<" "<<k<<endl;
  36. // getchar();
  37. if (!k||!x||!y) return;
  38. b[x][y]=1;
  39. dfs(pre[x][y][k][0],pre[x][y][k][1],pre[x][y][k][2]);
  40. if (pre[x][y][k][2]!=k) dfs(pre[x][y][k][0],pre[x][y][k][1],k^pre[x][y][k][2]);
  41. // if (pre[x][y][k][0]==x&&pre[x][y][k][1]==y) dfs(pre[x][y][k][0],pre[x][y][k][1],k^pre[x][y][k][2]);
  42. }
  43.  
  44. void out()
  45. {
  46. F(i,1,n)
  47. {
  48. F(j,1,m)
  49. if (b[i][j])
  50. {
  51. if (a[i][j]) printf("o");
  52. else printf("x");
  53. }
  54. else
  55. {
  56. printf("_");
  57. }
  58. printf("\n");
  59. }
  60. }
  61.  
  62. int main()
  63. {
  64. memset(dp,0x3f,sizeof dp);
  65. n=Getint();m=Getint();
  66. F(i,1,n) F(j,1,m)
  67. {
  68. a[i][j]=Getint();
  69. if(!a[i][j])
  70. {
  71. cnt++;
  72. dp[i][j][1<<(cnt-1)]=0;
  73. }
  74. }
  75. for (int k=1;k<(1<<cnt);++k)
  76. {
  77. F(i,1,n) F(j,1,m)
  78. {
  79. for (int x=(k-1)&k;x;x=(x-1)&k)
  80. {
  81. int tmp=dp[i][j][x]+dp[i][j][k^x]-a[i][j];
  82. if (tmp<dp[i][j][k])
  83. {
  84. dp[i][j][k]=tmp;
  85. pre[i][j][k][0]=i;
  86. pre[i][j][k][1]=j;
  87. pre[i][j][k][2]=x;
  88. }
  89. }
  90. if (dp[i][j][k]<inf)
  91. {
  92. qi.push(i);
  93. qj.push(j);
  94. inq[i][j]=1;
  95. }
  96. }
  97. while (!qi.empty())
  98. {
  99. int ni=qi.front(),nj=qj.front();
  100. qi.pop();qj.pop();
  101. inq[ni][nj]=0;
  102. F(i,0,3)
  103. {
  104. int ti=ni+mov[i][0],tj=nj+mov[i][1];
  105. if (ti<=0||ti>n||tj<=0||tj>m) continue;
  106. if (dp[ni][nj][k]+a[ti][tj]<dp[ti][tj][k])
  107. {
  108. dp[ti][tj][k]=dp[ni][nj][k]+a[ti][tj];
  109. pre[ti][tj][k][0]=ni;
  110. pre[ti][tj][k][1]=nj;
  111. pre[ti][tj][k][2]=k;
  112. if (!inq[ti][tj])
  113. {
  114. qi.push(ti);
  115. qj.push(tj);
  116. inq[ti][tj]=1;
  117. }
  118. }
  119. }
  120. }
  121. }
  122. F(i,1,n) F(j,1,m)
  123. {
  124. if (!a[i][j])
  125. {
  126. printf("%d\n",dp[i][j][(1<<cnt)-1]);
  127. dfs(i,j,(1<<cnt)-1);
  128. out();
  129. return 0;
  130. }
  131. }
  132. }

  

BZOJ 2595 [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]游览计划——斯坦纳树

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

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

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

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

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

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

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

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

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

  9. bzoj 2595 [Wc2008]游览计划(斯坦纳树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...

随机推荐

  1. windows下jdk环境变量配置

    JAVA_HOMEC:\Program Files\Java\jdk1.8.0_131 JMETER_HOMEC:\jmeter\jmeter3.2 CLASSPATH%JAVA_HOME%\lib; ...

  2. HDU 5469 Antonidas (树形DP,暴力)

    题意: 给一棵n节点的树图,每个点都是一个小写字母,要求找到两个点(a,b),从a->b的路径上形成了一个字符串为s.给出s,问是否存在这样的点对. 思路: 考虑一个点,要么从该点出发,要么在该 ...

  3. DRM 简介

    首先,我们对和DRM 相关的一些概念进行介绍. Buffer: 对于RAC 数据库,当一个数据块被读入到buffer cache后,我们就称其为buffer , cache fusion 会将这个bu ...

  4. 利用enum4linux 445端口+wordpress插件任意文件上传的一次渗透

    探测内网80端口发现目标IP 目标使用Apache  2.4.7web服务中间件 使用linux    Ubuntu系统 使用御剑扫描了目录 目录扫描到了 http://192.168.31.236/ ...

  5. 通过例子理解 k8s 架构【转】

    为了帮助大家更好地理解 Kubernetes 架构,我们部署一个应用来演示各个组件之间是如何协作的. 执行命令 kubectl run httpd-app --image=httpd --replic ...

  6. 计算机图形学(Conputer Graphics):非均匀有理B样条

    计算机图形学(Conputer Graphics):非均匀有理B样条 非均匀有理B样条(Non-Uniform Rational B-Spline)英文缩写,NURBS. 它是贝塞尔曲线的一个推广,而 ...

  7. linux下怎么修改mysql的字符集编码

    安装完的MySQL的默认字符集为 latin1 ,为了要将其字符集改为用户所需要的(比如utf8),就必须改其相关的配置文件:由于linux下MySQL的默认安装目录分布在不同的文件下:不像windo ...

  8. kubernetes概念

    kubernetes blog cluster cluster是计算.存储.和网络资源的集合,kubernetes利用这些资源运行各种基于容器的应用. master master是cluster的大脑 ...

  9. javascript顺序数组简单实现个二分查找

    直接上码了注释写得很详细: function bsearch(A,x){ //l:查找范围左 r:查找范围右 let l = 0, //查询范围左边界 r = A.length-1, //查找范围右边 ...

  10. Git学习——工作区和暂存区

    工作区就是我们的电脑上的git初始化目录.版本库就是我们工作区中的隐藏目录.git.版本库中分为两个部分:(1)stage(index)暂存区:git add <file>命令后file就 ...