Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 1171  Solved: 639
[Submit][Status][Discuss]

Description

小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰。

该部门有 n 个情报站,用 1 到 n 的整数编号。给出 m 对情报站 ui;vi 和费用 wi,表示情
报站 ui 和 vi 之间可以花费 wi 单位资源建立通道。
如果一个情报站经过若干个建立好的通道可以到达另外一个情报站,那么这两个情报站就
建立了通道连接。形式化地,若 ui 和 vi 建立了通道,那么它们建立了通道连接;若 ui 和 vi 均
与 ti 建立了通道连接,那么 ui 和 vi 也建立了通道连接。
现在在所有的情报站中,有 p 个重要情报站,其中每个情报站有一个特定的频道。小铭铭
面临的问题是,需要花费最少的资源,使得任意相同频道的情报站之间都建立通道连接。

Input

第一行包含三个整数 n;m;p,表示情报站的数量,可以建立的通道数量和重要情报站的数

量。接下来 m 行,每行包含三个整数 ui;vi;wi,表示可以建立的通道。最后有 p 行,每行包含
两个整数 ci;di,表示重要情报站的频道和情报站的编号。

Output

输出一行一个整数,表示任意相同频道的情报站之间都建立通道连接所花费的最少资源总量。

Sample Input

5 8 4
1 2 3
1 3 2
1 5 1
2 4 2
2 5 1
3 4 3
3 5 1
4 5 1
1 1
1 2
2 3
2 4

Sample Output

4

HINT

选择 (1; 5); (3; 5); (2; 5); (4; 5) 这 4 对情报站连接。

对于 100% 的数据,0 <ci <= p <= 10; 0 <ui;vi;di <= n <= 1000; 0 <= m <= 3000; 0 <= wi <=
20000。
 

Source

斯坦纳森林

设$f[i][sta]$表示$i$号节点,与关键节点的联通性为$sta$时的最小值

假设我们已经求出了$f$

那么我们令$g[sta]$表示,颜色联通性为$sta$时的最小值

$g$比较好求,枚举子集转移就可以

$f$的话,如果学过斯坦纳树也比较好求

按照套路,两种转移方法,一种是枚举子集,一种是SPFA

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 1e6 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') {x = x * + c - ''; c = getchar();}
return x * f;
}
int N, M, P;
struct node {
int u, v, w, nxt;
}E[MAXN];
int head[MAXN], num = ;
inline void AddEdge(int x, int y,int z) {
E[num].u = x; E[num].v = y; E[num].w = z;
E[num].nxt = head[x]; head[x] = num++;
}
struct Point {
int color, ID;
}a[MAXN];
int f[][], g[];
int vis[MAXN], sum[MAXN];
queue<int>q;
void SPFA(int now) {
while(q.size() != ) {
int p = q.front(); q.pop(); vis[p] = ;
for(int i = head[p]; i != -; i = E[i].nxt) {
int v = E[i].v;
if(f[v][now] > f[p][now] + E[i].w) {
f[v][now] = f[p][now] + E[i].w;
if(!vis[v]) vis[v] = , q.push(v);
}
}
}
}
int tmp[];
bool check(int sta) {
memset(tmp, , sizeof(tmp));
for(int i = ; i <= ; i++)
if(sta & ( << i - )) tmp[a[i].color]++;
for(int i = ; i <= ; i++)
if(tmp[i] && tmp[i] != sum[i]) return ;
return ;
}
int main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
memset(head, -, sizeof(head));
N = read(), M = read(), P = read();
for(int i = ; i <= M; i++) {
int x = read(), y = read(), z = read();
AddEdge(x, y, z);AddEdge(y, x, z);
}
memset(f, 0x3f, sizeof(f));
memset(g, 0x3f, sizeof(g));
for(int i = ; i <= P; i++)
a[i].color = read(), a[i].ID = read(), sum[a[i].color]++,f[a[i].ID][ << (i - )] = ;
int limit = ( << P) - ;
for(int sta = ; sta <= limit; sta++) {
for(int i = ; i <= N; i++) {
for(int S = sta; S; S = (S - ) & sta)
f[i][sta] = min(f[i][sta], f[i][S] + f[i][sta - S]);
q.push(i),vis[i] = ;
}
SPFA(sta);
}
for(int sta = ; sta <= limit; sta++)
for(int i = ; i <= N; i++)
g[sta] = min(g[sta], f[i][sta]);
for(int sta = ; sta <= limit; sta++)
if(check(sta))
for(int S = sta; S; S = (S - ) & sta)
if(check(S))
g[sta] = min(g[sta], g[S] + g[sta - S]);
printf("%d", g[( << P) - ]);
return ;
}

BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. bzoj1402 Ticket to Ride 斯坦纳树 + 状压dp

    给定\(n\)个点,\(m\)条边的带权无向图 选出一些边,使得\(4\)对点之间可达,询问权值最小为多少 \(n \leqslant 30, m \leqslant 1000\) 首先看数据范围,\ ...

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

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

随机推荐

  1. 黑客之google入侵网站常用方式 2

    一: 在搜索框上输入: “index of/ ” inurl:lib 再按搜索你将进入许多图书馆,并且一定能下载自己喜欢的书籍. 在搜索框上输入: “index of /” cnki 再按搜索你就可以 ...

  2. Spring Boot—19Session

    pom.xm <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  3. Debian 8 升级到 9 Debian 9 How to upgrade Debian 8 Jessie to Debian 9 Stretch

    How to upgrade Debian 8 Jessie to Debian 9 Stretch Contents 1. Objective 2. What's New 3. Preparatio ...

  4. Flutter Stack布局中定位的方式

    前言 想要记录一下Stack布局中,定位的两种方式 代码 //……省略无关代码…… child: new Column( children: <Widget>[ new SizedBox( ...

  5. 初次使用git就遭遇不测,提示没有这个服务连接和需要配置git的一个http参数 NO network connection,SSl host could not be verified ...

    第一次使用git 拉取服务上的项目到本地,结果,在拿到访问的url地址后,输入用户名密码,失败了. --eclispe  4.5.3 继承了git客户端插件的版本 ------下一步后,报错 NO n ...

  6. zabbix系列之三——安装报错

    1Zabbix_server启动失败 1.1查看日志:vi /var/log/zabbix/zabbix_server.log zabbix_server [23500]: cannot open l ...

  7. 关于C#线程,线程池和并行运算的简单使用和对比

    转自:https://www.cnblogs.com/jeffwongishandsome/archive/2010/11/12/1876137.html 先大概看一下控制台应用程序的Main方法的主 ...

  8. django新建项目,连接mysql数据库

    安装django,进入Django目录,运行 python setup.py install 在workplace目录下新建一个名为site01的项目: cd workplacedjango-admi ...

  9. Python学习---Form拾遗180322

    Form操作之错误信息操作 1. 用户发送请求过来 2. for 循环对字段进行正则表达式的验证  fields.clean(value) 3. 自定义clean_字段() 进行名字段值正确性的校验 ...

  10. 搭建企业级NFS网络文件共享服务[二]

    1.1.8 NFS问题总结 1.问:使用showmount -e 127.0.0.1后报clnt_create: RPC: Program not registered错误 答:顺序不对,重启nfs服 ...