题目链接

题意:

给出\(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. webpack打包 The 'mode' option has not been set, webpack will fallback to

    webpack 打包报错 The 'mode' option has not been set, webpack will fallback to 'production' for,Module no ...

  2. golang中的定向通道(Directional channels)

    好像第一次看到这个知识点,作个记录. 注意通道在只能发射或只能接收信息时,<-这个符号放置的位置. package main import "fmt" import &quo ...

  3. 验证登录的前世今生:session、cookie

    参考地址:彻底理解cookie,session,token 使用JSON Web Token设计单点登录系统 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录 ...

  4. class与class的继承

    class Point{ constructor(x,y){ this.x = x; this.y = y; } toString(){ return '(' + this.x + ',' + thi ...

  5. Python学习记录:括号配对检测问题

    Python学习记录:括号配对检测问题 一.问题描述 在练习Python程序题的时候,我遇到了括号配对检测问题. 问题描述:提示用户输入一行字符串,其中可能包括小括号 (),请检查小括号是否配对正确, ...

  6. SQL查询--内连接、外连接、自连接查询

    先创建2个表:学生表和教师表   1.内连接: 在每个表中找出符合条件的共有记录.[x inner join y on...] 第一种写法:只用where SELECT t.TEACHER_NAME, ...

  7. ViewTool Hollong BLE Sniffer Support Linux OS Introduction

    ViewTool Hollong BLE Sniffer Support Linux OS Introduction 1. Download Software:http://www.viewtool. ...

  8. 使用paramiko模块进行封装,远程操作linux主机

    import time import paramiko class HandleParamiko: ''' 定义一个linux处理类 ''' def __init__(self, hostname, ...

  9. Linux shell脚本编程及系统启动实践

    1.编写脚本,接受二个位置参数,magedu和/www,判断系统是否有magedu,如果没有则自动创建magedu用户,并自动设置家目录为/www [root@test qiuhom]#cat che ...

  10. js判断undefined和null

    js判断undefined var exp = undefined; if (typeof(exp) == "undefined") { alert("undefined ...