传送门

题意:

给出\(n\)个重要点,还有其余\(m\)个点,\(p\)条边。

现在要在这\(n+m\)个点中挖几口水井,每个地方的费用为\(w_i\)。连接边也有费用。

问使得这\(n\)个地点都有水井(或直接、间接与水井相连)的最小代价。

思路:

有点巧妙。。建立一个虚点连向所有点,边权为\(w_i\)。然后直接求以\(0\)为根的斯坦纳树即可,最后再子集\(dp\)一下就行。

原理就是,此时这\(n\)个点连通,并且以\(0\)为根,脑补一下即可发现:要么直接与\(0\)相连,要么间接相连,直接相连就是这里挖井,间接相连的话就是通过其它地方引水。

代码如下:

  1. /*
  2. * Author: heyuhhh
  3. * Created Time: 2019/11/27 14:23:05
  4. */
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <vector>
  8. #include <cmath>
  9. #include <set>
  10. #include <map>
  11. #include <iomanip>
  12. #include <queue>
  13. #include <cstdio>
  14. #include <cstring>
  15. #define MP make_pair
  16. #define fi first
  17. #define se second
  18. #define sz(x) (int)(x).size()
  19. #define all(x) (x).begin(), (x).end()
  20. #define INF 0x3f3f3f3f
  21. #define Local
  22. #ifdef Local
  23. #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  24. void err() { std::cout << '\n'; }
  25. template<typename T, typename...Args>
  26. void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  27. #else
  28. #define dbg(...)
  29. #endif
  30. void pt() {std::cout << '\n'; }
  31. template<typename T, typename...Args>
  32. void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
  33. using namespace std;
  34. typedef long long ll;
  35. typedef pair<int, int> pii;
  36. //head
  37. const int N = 1010, M = 10005, P = 6;
  38. int n, m, p;
  39. struct Edge {
  40. int v, w, next;
  41. }e[M << 1];
  42. int head[N], tot;
  43. void adde(int u, int v, int w) {
  44. e[tot].v = v; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++;
  45. }
  46. int dp[N][1 << P];
  47. queue <int> q;
  48. bool in[N];
  49. void spfa(int s) {
  50. while(!q.empty()) {
  51. int u = q.front(); q.pop(); in[u] = 0;
  52. for(int i = head[u]; i != -1; i = e[i].next) {
  53. int v = e[i].v;
  54. if(dp[v][s] > dp[u][s] + e[i].w) {
  55. dp[v][s] = dp[u][s] + e[i].w;
  56. if(!in[v]) q.push(v), in[v] = 1;
  57. }
  58. }
  59. }
  60. }
  61. int g[1 << P];
  62. void run(){
  63. memset(head, -1, sizeof(head)); tot = 0;
  64. for(int i = 1; i <= n + m; i++) {
  65. int w; cin >> w;
  66. adde(0, i, w);
  67. adde(i, 0, w);
  68. }
  69. for(int i = 1; i <= p; i++) {
  70. int u, v, w; cin >> u >> v >> w;
  71. adde(u, v, w); adde(v, u, w);
  72. }
  73. memset(dp, INF, sizeof(dp));
  74. memset(g, INF, sizeof(g));
  75. for(int i = 1; i <= n; i++) {
  76. dp[i][1 << (i - 1)] = 0;
  77. }
  78. int lim = (1 << n);
  79. for(int S = 1; S < lim; S++) {
  80. for(int i = 0; i <= n + m; i++) {
  81. for(int s = (S - 1) & S; s; s = (s - 1) & S) {
  82. dp[i][S] = min(dp[i][S], dp[i][s] + dp[i][S - s]);
  83. }
  84. if(dp[i][S] < INF) q.push(i), in[i] = 1;
  85. }
  86. spfa(S);
  87. g[S] = dp[0][S];
  88. }
  89. for(int S = 1; S < lim; S++) {
  90. for(int s = (S - 1) & S; s; s = (s - 1) & S) {
  91. g[S] = min(g[S], g[s] + g[S - s]);
  92. }
  93. }
  94. cout << g[lim - 1] << '\n';
  95. }
  96. int main() {
  97. ios::sync_with_stdio(false);
  98. cin.tie(0); cout.tie(0);
  99. cout << fixed << setprecision(20);
  100. while(cin >> n >> m >> p) run();
  101. return 0;
  102. }

【hdu3311】Dig The Wells(斯坦纳树+dp)的更多相关文章

  1. HDU - 3311: Dig The Wells (斯坦纳树)

    题意:给你n个寺庙,m个村庄,p条路,现在你要在这n+m个位置中选出若干个位置打井,每个位置打井的费用会告诉你,同时p条路也有修建费用,现在每个寺庙都住着一个和尚,问你最小的费用让这n个和尚都能喝上水 ...

  2. 【bzoj4006】[JLOI2015]管道连接(斯坦纳树+dp)

    题目链接 题意: 给出\(n\)个点,\(m\)条边,同时给出\(p\)个重要的点以及对应特征. 现在要选出一些边,问使得这\(p\)个所有特征相同的点相连,问最小代价. 思路: 斯坦纳树的应用场景一 ...

  3. HDU 4085 斯坦纳树+DP

    https://cn.vjudge.net/problem/HDU-4085 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价 从前k个点中任取一个使其和后k个点 ...

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

    [Luogu4294] 题解 : 斯坦纳树 \(dp[i][j]\) 表示以\(i\)号节点为根,当前状态为\(j\)(与\(i\)连通的点为\(1\)) 当根\(i\)不改变时状态转移方程是: \( ...

  5. HDU 3311 Dig The Wells(斯坦纳树)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3311 [题意] 给定k座庙,n个其他点,m条边,点权代表挖井费用,边权代表连边费用,问使得k座庙里 ...

  6. 【BZOJ2595】游览计划(状压DP,斯坦纳树)

    题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...

  7. hdu4085 Peach Blossom Spring 斯坦纳树,状态dp

    (1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s ...

  8. bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...

  9. BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】

    传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Stein ...

随机推荐

  1. hidraw设备简要分析

    关键词:hid.hidraw.usbhid.hidp等等. 下面首先介绍hidraw设备主要用途,然后简要分析hidraw设备驱动(但是不涉及到相关USB/Bluwtooth驱动),最后分析用户空间接 ...

  2. mtu测试

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/jeromezmzx007/article ...

  3. leetcode回溯算法--基础难度

    都是直接dfs,算是巩固一下 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任何字母. 思路 一直 ...

  4. git集成idea

    1.Git Gui的使用 2.Ssh key 介绍及使用 3.Idea配置使用并使用git Git Gui的使用 Ssh key 介绍及使用 Ssh key介绍 我理解的就是每台电脑上会产生出一个ss ...

  5. The Preliminary Contest for ICPC Asia Shenyang 2019

    传送门 B. Dudu's maze 题意: 是什么鬼东西???我读题可以读半小时QAQ 给出一张无向图,一个人在里面收集糖果,每个点都有一个糖果,特殊点除外.当他第一次进入特殊点时,会随机往一条边走 ...

  6. wepy安装后提示Cannot read property 'addDeps'

    最近准备做一个微信小程序,以前一直用的小程序原始api做,但是这次准备用一个框架来做练习,当然在做之前需要比较一下现在小程序框架的优缺点. 经过认真挑选,选定wepy,Taro,uni-app,mpv ...

  7. 向技术领先的华为说No,就是对国家的通信前景说No!

    历史已经证明了,任何一项可以加速人员.物资.能源.金钱.信息迁移的技术,都会让社会原有的生产力成倍地增长.中国在互联网.移动互联网保持令整个世界震惊的飞速发展,以BAT为首的诸多商业帝国建立,还有人们 ...

  8. C#开发BIMFACE系列23 服务端API之获取模型数据8:获取模型链接信息

    系列目录     [已更新最新开发文章,点击查看详细] 在Revit等BIM设计工具中可以给模型的某个部位添加链接信息.即类似于在Office Word.Excel 中给一段文字添加本地文件链接或者网 ...

  9. Java连载47-多态基础语法、作用

    一.多态的语法 1.两个类之间没有继承关系的,使用多态是不能编译的. 2.无论向上还是向上转型,都需要有继承关系. 3.什么时候需要向下转型? 当调用的方法或者属性是子类型特有的,在父类型中不存在,就 ...

  10. SpringBoot2.0.4部署在tomcat容器中

    1.  修改启动类继承自SpringBootServletInitializer. 2. 重写config方法: @Overrideprotected SpringApplicationBuilder ...