题目链接

题意:

给出\(n\)个点,\(m\)条边,同时给出\(p\)个重要的点以及对应特征。

现在要选出一些边,问使得这\(p\)个所有特征相同的点相连,问最小代价。

思路:

斯坦纳树的应用场景一般就为:使得一些点连通,在此基础上,允许连接一些其它的点,加入一些其它的边。可以说最小生成树是斯坦纳树的一个特例。

那么这个题首先看到要使\(p\)个点连通,那么就可以斯坦纳树搞一搞。

因为题目要求特征相同的点相连,斯坦纳树搞出来后还不够,他要求的是一个斯坦纳树森林。

我们将特征相同的所有点扣出来,然后作个子集\(dp\)就行了。

感觉这应该是一道斯坦纳树的标准题?

详见代码:

/*
* 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 = 1005, M = 3005, P = 11; int n, m, p;
int c[P], d[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], chk[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], sum[P], tmp[P];
bool ok(int s) {
memset(tmp, 0, sizeof(tmp));
for(int i = 1; i <= p; i++) if((s >> (i - 1)) & 1) ++tmp[d[i]];
for(int i = 1; i <= p; i++) if(tmp[d[i]] && tmp[d[i]] != sum[d[i]]) return false;
return true;
}
void run(){
memset(head, -1, sizeof(head)); tot = 0;
for(int i = 1; i <= m; 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 <= p; i++) {
cin >> d[i] >> c[i];
dp[c[i]][1 << (i - 1)] = 0;
++sum[d[i]];
}
int lim = (1 << p);
for(int S = 1; S < lim; S++) {
for(int i = 1; i <= n; 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);
for(int i = 1; i <= n; i++) g[S] = min(g[S], dp[i][S]);
}
for(int i = 1; i < lim; i++) if(ok(i)) {
for(int j = i; j; j = (j - 1) & i) if(ok(j)){
g[i] = min(g[i], g[j] + g[i ^ j]);
}
}
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;
}

【bzoj4006】[JLOI2015]管道连接(斯坦纳树+dp)的更多相关文章

  1. BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)

    Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1171  Solved: 639[Submit][Status][Discuss] Descripti ...

  2. BZOJ4006 JLOI2015 管道连接(斯坦纳树生成森林)

    4006: [JLOI2015]管道连接 Time Limit: 30 Sec Memory Limit: 128 MB Description 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的 ...

  3. 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp

    题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...

  4. BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)

    题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...

  5. 【BZOJ4774/4006】修路/[JLOI2015]管道连接 斯坦纳树

    [BZOJ4774]修路 Description 村子间的小路年久失修,为了保障村子之间的往来,法珞决定带领大家修路.对于边带权的无向图 G = (V, E),请选择一些边,使得1 <= i & ...

  6. 洛谷P3264 [JLOI2015]管道连接 (斯坦纳树)

    题目链接 题目大意:有一张无向图,每条边有一定的花费,给出一些点集,让你从中选出一些边,用最小的花费将每个点集内的点相互连通,可以使用点集之外的点(如果需要的话). 算是斯坦纳树的入门题吧. 什么是斯 ...

  7. bzoj 4006 [JLOI2015]管道连接——斯坦纳树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 除了模板,就是记录 ans[ s ] 表示 s 合法的最小代价.合法即保证 s 里同一 ...

  8. bzoj 4006 管道连接 —— 斯坦纳树+状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 用斯坦纳树求出所有关键点的各种连通情况的代价,把这个作为状压(压的是集合选择情况)的初 ...

  9. 【LuoguP3264】[JLOI2015] 管道连接(斯坦那树)

    题目链接 题目描述 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰.该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情报站 u ...

  10. [bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp

    管道连接 bzoj-4006 JLOI-2015 题目大意:给定一张$n$个节点$m$条边的带边权无向图.并且给定$p$个重要节点,每个重要节点都有一个颜色.求一个边权和最小的边集使得颜色相同的重要节 ...

随机推荐

  1. ThinkPHP数据库驱动之mysql事物回滚

    1.开启事务方法 startTrans()2.事务提交方法 commit()3.事务回滚方法 rollback() 用法例子: $order = M(‘order’); $allAdded = tru ...

  2. 关于xshell连接limux界面按退格键不正常的问题

    这个问题通过修改xshell终端属性可以解决,步骤如下: "文件" -> "属性" -> "终端" -> "键盘 ...

  3. chattr lsattr linux file system attributes - linux 文件系统扩展属性

    我们使用 linux 文件系统扩展属性,能够对linux文件系统进行进一步保护:从而给文件 赋予一些额外的限制:在有些情况下,能够对我们的系统提供保护: chattr命令用来改变文件属性.这项指令可改 ...

  4. Python语法速查: 2. 列表、元组、字典、集合操作

    返回目录 (1)通用序列操作 “序列”表示索引为非负整数的有序对象集合,列表.元组.字符串都属于序列.区别在于:列表是可变的,而元组和字符串是不可变的.序列的通用操作他们都可以用. 操作或方法 简述 ...

  5. 一个版本烧录过程中记录:fdisk、mkfs.ext4、make_ext4fs、img2simg、simg2img

    关键词:dd.fdisk.mkfs.ext4.make_ext4fs.img2simg.simg2img等等. 一个典型的嵌入式系统是由uboot+kernel+rootfs组成的,其中uboot和k ...

  6. 阿里云ubuntu 16.04 搭建pptpd 第二版

    前言:1.我常用的服务器在国内,但我又有某方面的需求,所以想要搭建一个pptpd的服务器    2.但我又不常用,所以感觉阿里云包年包月的不划算,所以准备采用阿里云按量付费的实例来搭建pptpd,并形 ...

  7. node.js守护进程问题的解决

    最近自己写了一个node.js来读取redis数据,编写完成后按理来说加& 应该是有效的 nohup node redis.js & 但是每次关闭终端后这个进程就自动停止了,百度了下 ...

  8. 关于OpenCASCADE数组序列的起始值

    C/C++的数组是从0开始计算的,5个值的数组则下标会对应 0, 1, 2, 3, 4. 在数学上可能不这么数,我所知道的 Mathematica 内的 List 是从 1 开始作为下标的. Open ...

  9. limit的优化

    SELECT * FROM t_fly WHERE fly_id IN (8888,1,24,6666); 查询速度很快,对于一些过万数据的查询,mysql也能轻松的查询出来

  10. acwing 25. 剪绳子

    习题地址 https://www.acwing.com/problem/content/description/24/ 题目描述 给你一根长度为 nn 绳子,请把绳子剪成 mm 段(mm.nn 都是整 ...