【hdu3311】Dig The Wells(斯坦纳树+dp)
题意:
给出\(n\)个重要点,还有其余\(m\)个点,\(p\)条边。
现在要在这\(n+m\)个点中挖几口水井,每个地方的费用为\(w_i\)。连接边也有费用。
问使得这\(n\)个地点都有水井(或直接、间接与水井相连)的最小代价。
思路:
有点巧妙。。建立一个虚点连向所有点,边权为\(w_i\)。然后直接求以\(0\)为根的斯坦纳树即可,最后再子集\(dp\)一下就行。
原理就是,此时这\(n\)个点连通,并且以\(0\)为根,脑补一下即可发现:要么直接与\(0\)相连,要么间接相连,直接相连就是这里挖井,间接相连的话就是通过其它地方引水。
代码如下:
/*
* Author: heyuhhh
* Created Time: 2019/11/27 14:23:05
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#include <queue>
#include <cstdio>
#include <cstring>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1010, M = 10005, P = 6;
int n, m, p;
struct Edge {
int v, w, next;
}e[M << 1];
int head[N], tot;
void adde(int u, int v, int w) {
e[tot].v = v; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++;
}
int dp[N][1 << P];
queue <int> q;
bool in[N];
void spfa(int s) {
while(!q.empty()) {
int u = q.front(); q.pop(); in[u] = 0;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(dp[v][s] > dp[u][s] + e[i].w) {
dp[v][s] = dp[u][s] + e[i].w;
if(!in[v]) q.push(v), in[v] = 1;
}
}
}
}
int g[1 << P];
void run(){
memset(head, -1, sizeof(head)); tot = 0;
for(int i = 1; i <= n + m; i++) {
int w; cin >> w;
adde(0, i, w);
adde(i, 0, w);
}
for(int i = 1; i <= p; i++) {
int u, v, w; cin >> u >> v >> w;
adde(u, v, w); adde(v, u, w);
}
memset(dp, INF, sizeof(dp));
memset(g, INF, sizeof(g));
for(int i = 1; i <= n; i++) {
dp[i][1 << (i - 1)] = 0;
}
int lim = (1 << n);
for(int S = 1; S < lim; S++) {
for(int i = 0; i <= n + m; i++) {
for(int s = (S - 1) & S; s; s = (s - 1) & S) {
dp[i][S] = min(dp[i][S], dp[i][s] + dp[i][S - s]);
}
if(dp[i][S] < INF) q.push(i), in[i] = 1;
}
spfa(S);
g[S] = dp[0][S];
}
for(int S = 1; S < lim; S++) {
for(int s = (S - 1) & S; s; s = (s - 1) & S) {
g[S] = min(g[S], g[s] + g[S - s]);
}
}
cout << g[lim - 1] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n >> m >> p) run();
return 0;
}
【hdu3311】Dig The Wells(斯坦纳树+dp)的更多相关文章
- HDU - 3311: Dig The Wells (斯坦纳树)
题意:给你n个寺庙,m个村庄,p条路,现在你要在这n+m个位置中选出若干个位置打井,每个位置打井的费用会告诉你,同时p条路也有修建费用,现在每个寺庙都住着一个和尚,问你最小的费用让这n个和尚都能喝上水 ...
- 【bzoj4006】[JLOI2015]管道连接(斯坦纳树+dp)
题目链接 题意: 给出\(n\)个点,\(m\)条边,同时给出\(p\)个重要的点以及对应特征. 现在要选出一些边,问使得这\(p\)个所有特征相同的点相连,问最小代价. 思路: 斯坦纳树的应用场景一 ...
- HDU 4085 斯坦纳树+DP
https://cn.vjudge.net/problem/HDU-4085 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价 从前k个点中任取一个使其和后k个点 ...
- [WC2008]游览计划(斯坦纳树)
[Luogu4294] 题解 : 斯坦纳树 \(dp[i][j]\) 表示以\(i\)号节点为根,当前状态为\(j\)(与\(i\)连通的点为\(1\)) 当根\(i\)不改变时状态转移方程是: \( ...
- HDU 3311 Dig The Wells(斯坦纳树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3311 [题意] 给定k座庙,n个其他点,m条边,点权代表挖井费用,边权代表连边费用,问使得k座庙里 ...
- 【BZOJ2595】游览计划(状压DP,斯坦纳树)
题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...
- 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 ...
- bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...
- BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】
传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Stein ...
随机推荐
- DataPump遭遇ORA-06512&ORA-39080&ORA-01403错误案例
最近使用数据泵(DataPump)比较多,遇到了奇奇怪怪的问题,似乎Apply了补丁PSU 10.2.0.5.180717后,DataPump的问题就格外多.如下所示: expdp system/xx ...
- Linux和Windows的区别
1. 软件与支持 • Windows 平台:数量和质量的优势,不过大部分为收费软件:由微软官方提供重要支持和服务: • Linux 平台:大都为开源自由软件,用户可以修改定制和再发布,由于基本免费没有 ...
- Xposed优缺点和入门
Xposed框架的原理是替换安卓系统/System/bin目录下的文件,从而实现对系统某些功能的替换,进而给予基于 Xposed 框架开发的App更多权限. 优点:1.功能强大2.执行效率快缺点:1. ...
- python爬虫之csv文件
一.二维数据写入csv文件 题目要求: 读入price2016.csv文件,将其中的数据读出,将数字部分计算百分比后输出到price2016out.csv文件中 知识点: 对于列表中存储的二维数据, ...
- 融云技术分享:解密融云IM产品的聊天消息ID生成策略
本文来自融云技术团队原创分享,原文发布于“融云全球互联网通信云”公众号,原题<如何实现分布式场景下唯一 ID 生成?>,即时通讯网收录时有部分改动. 1.引言 对于IM应用来说,消息ID( ...
- vue的基础概念和语法01
vue的特点和web开发中的常见高级功能 解耦视图和数据 可复用的组件 前端路由技术 状态管理 虚拟DOM 数据响应式 不是所有元素操作都Vue都会监听并实现数据响应式 //push方法:追加 thi ...
- 洛谷 P2176(最短路)
###题目链接 洛谷 P2176 ### 题目大意: 已知农夫从 1 走到 N 点,一定走的是最短路.问你将某条路的长度变为其两倍后,农夫从 1 走到 N 点的路程最大增加多少,输出最大增量. 分析: ...
- P站全新官方精选集Pixivision
P站是一个主要由日本艺术家所组成的虚拟社群,主打插画.漫画.二次元作品网上沟通. 不过好消息是,P站全新的精选网站Pixivision上线了,多种语言界面,国内用户访问毫无压力. 近期精选的一系列作品 ...
- 知识图谱如何运用于RecomSys
将知识图谱作为辅助信息引入到推荐系统中可以有效地解决传统推荐系统存在的稀疏性和冷启动问题,近几年有很多研究人员在做相关的工作.目前,将知识图谱特征学习应用到推荐系统中主要通过三种方式——依次学习.联合 ...
- ASP.NET 表单验证
静态脚本 oncilentClick() 静态使用方法 也可以$获取ID动态添加脚本 1.Response.Write(); 2.通过Register方式 3.Attribus方式根据控件ID进行添加 ...