4006: [JLOI2015]管道连接

Time Limit: 30 Sec  Memory Limit: 128 MB

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。

算法讨论:

斯坦纳树生成森林。题解再补。

代码:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue> using namespace std;
const int N = 1000 + 5;
const int inf = 0xf0f0f0f; int n, m, p, cnt, channel, tot_channel;
int g[1025], f[N][1025], head[N], inque[N];
queue <int> q; struct Edge {
int from, to, dis, next;
}edges[6005]; struct Data {
int c, num;
bool operator < (const Data &STD) const {
return c < STD.c;
}
}key[11]; void insert(int from, int to, int dis) {
++ cnt;
edges[cnt].from = from; edges[cnt].to = to; edges[cnt].dis = dis;
edges[cnt].next = head[from]; head[from] = cnt;
} void spfa(int State) {
while(!q.empty()) {
int x = q.front(); q.pop();
inque[x] = 0;
for(int i = head[x]; i; i = edges[i].next) {
int v = edges[i].to;
if(f[v][State] > f[x][State] + edges[i].dis) {
f[v][State] = f[x][State] + edges[i].dis;
if(!inque[v]) {
inque[v] = 1;
q.push(v);
}
}
}
}
} int solve() {
int U = 1 << channel;
for(int State = 0; State < U; ++ State) {
for(int i = 1; i <= n; ++ i) {
for(int s = (State - 1) & State; s; s = (s - 1) & State)
f[i][State] = min(f[i][State], f[i][s] + f[i][State - s]);
if(f[i][State] != inf) q.push(i), inque[i] = 1;
}
spfa(State);
}
int ans = inf;
for(int i = 1; i <= n; ++ i) ans = min(ans, f[i][U - 1]);
return ans;
} #define stone_
int main() {
#ifndef stone_
freopen("channel.in", "r", stdin);
freopen("channel.out", "w", stdout);
#endif int u, v, w;
scanf("%d%d%d", &n, &m, &p);
for(int i = 1; i <= m; ++ i) {
scanf("%d%d%d", &u, &v, &w);
insert(u, v, w); insert(v, u, w);
}
for(int i = 1; i <= p; ++ i)
scanf("%d%d", &key[i].c, &key[i].num);
sort(key + 1, key + p + 1);
for(int i = 1; i <= p; ++ i) {
if(key[i].c != key[i - 1].c) ++ tot_channel;
key[i].c = tot_channel;
}
int U = 1 << tot_channel;
memset(g, 0xf, sizeof g);
for(int State = 0; State < U; ++ State) {
memset(f, 0xf, sizeof f);
channel = 0;
for(int i = 1; i <= p; ++ i)
if(State & 1 << (key[i].c - 1)) {
f[key[i].num][1 << channel] = 0;
channel ++;
}
g[State] = solve();
}
for(int State = 0; State < U; ++ State) {
for(int s = (State - 1) & State; s; s = (s - 1) & State)
g[State] = min(g[State], g[s] + g[State - s]);
}
printf("%d\n", g[U - 1]); #ifndef stone_
fclose(stdin); fclose(stdout);
#endif
return 0;
}

BZOJ4006 JLOI2015 管道连接(斯坦纳树生成森林)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Android开源项目及库搜集

    TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending,github搜索:https://github.com/ ...

  2. 在YouCompleteMe+Syntastic中添加和取消对C++11的支持

    添加对c++11的支持: /.vimrc中添加: let g:syntastic_cpp_compiler = 'g++'  "change the compiler to g++ to s ...

  3. 钢管下料问题2(剩余材料最少)lingo求解

    大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang !钢管下料问题2(剩余材料最少) 题目: 钢管原料   每根19m 客户需求   4m   50根 ...

  4. asp.net 中的错误跳转 customerrors 对html文件不起作用

    在配置web.config时发现customerrors对aspx文件是起作用的,我想通过customerrors来判断是否有html文件时,却不起作用? 这是为什么,如果要起作用.net里该如何操作 ...

  5. 手游与App测试如何快速转型? —— 过来人科普手游与App测试四大区别

    随着智能设备的普及和移动互联网的兴起,各家互联网巨头纷纷在往移动端布局和转型,同时初创的移动互联网公司也都盯着这个市场希望分一杯羹.在这个大环境下,互联网的重心已经慢慢从Web端转向了移动端,而移动端 ...

  6. Java中BigDecimal的8种舍入模式是怎样的

    Java中BigDecimal的8种舍入模式是怎样的?下面长沙欧柏泰克软件学院和大家一起来学习下吧:  java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecima ...

  7. ubuntu14.04折腾迅雷xware

    迅雷一直没有出linux版,wine不想去弄.linux下虽然也有各种bt软件,无奈我试用后却发现速度远比不上迅雷,甚至有些资源根本找不到.而有些迅雷的专用链接,更是没法下(原谅我2M的小水管,却喜欢 ...

  8. pyqt时间

    # -*- coding: utf-8 -*-__author__ = 'Administrator'from PyQt4 import QtCore, QtGui class Help(QtGui. ...

  9. mybatis 调用mysql存储过程 带输出输入参数

    http://lohasle.iteye.com/blog/1669879 存储过程都是一样的,只是根据自己的喜好,可以用MAP或者JAVABEAN传递参数. -- ----------------- ...

  10. [原创作品]web网页中的锚点

    因为近来在从事web前端开发的工作,所以写的文章也都是关于web这一块.以后将分享算法和web高级编程的内容,很多公司的web前端不够重视,以为是很low-level,给的待遇也很一般,其实,这都是很 ...