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. Linux 下安装python软件包

    1.安装setuptools 下载地址:https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py 解压: tar zxvf set ...

  2. shell中的eval

    eval语法 eval arg1 arg2 ... eval的作用就是将后面的参数arg1 arg2等等当成一个pipeline,然后重新执行shell处理pipeline的流程(有关pipeline ...

  3. css中的颜色值

    下面是比较适合在测试页面中用来设置背景颜色的淡颜色,最好记住一些,dark.blue.red.green.gray.olive颜色较深.

  4. [T]各种字符串Hash函数比较

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

  5. 需要熟悉的几个调试命令:objdump/pmap/ldd/stace

    最近要编译很多库,还涉及到若干进程操作,所以就把相关的命令记录下来. 一,objdump命令 该命令适用于ELF可执行文件,常用的命令如下: objdump -h xx.o : 输出ELF文件的各个段 ...

  6. Codeforces 22B Bargaining Table

    http://www.codeforces.com/problemset/problem/22/B 题意:求出n*m的方格图中全是0的矩阵的最大周长 思路:枚举 #include<cstdio& ...

  7. bzoj1624 [Usaco2008 Open] Clear And Present Danger 寻宝之路

    Description     农夫约翰正驾驶一条小艇在牛勒比海上航行.     海上有N(1≤N≤100)个岛屿,用1到N编号.约翰从1号小岛出发,最后到达N号小岛.一 张藏宝图上说,如果他的路程上 ...

  8. jquery图片3D旋绕效果 rotate3Di的操作

    这是一个图片效果,很简单实用,只需要一个"rotate3Di.js"的插件就行, 关于rotate的用法有如下几种: $(选择器).rotate3Di(30); //把图片3D旋转 ...

  9. hdu 5423 Rikka with Tree(dfs)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  10. Maven .m2 setting.xml配置

    settings.xml <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="h ...