[bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp
管道连接 bzoj-4006 JLOI-2015
题目大意:给定一张$n$个节点$m$条边的带边权无向图。并且给定$p$个重要节点,每个重要节点都有一个颜色。求一个边权和最小的边集使得颜色相同的重要节点互相连通。
注释:$1\le c_i \le p \le 10$,$1\le u_i,v_i,d_i\le n\le 10^3$,$0\le m\le 3\cdot 10^3$,$0\le w_i\le 2\cdot 10^4$。其中$c_i$和$d_i$分别是第$i$个节点的颜色和编号。
想法:发现这鬼东东和斯坦纳树很像啊。
我们先对$p$个点求出斯坦纳树,存入$f[s][i]$表示状态为$s$的重要节点被选取当前选到了$i$。
那么我们考虑怎么对这个颜色进行处理?
因为颜色个数也比较少对吧,不难想到状压$dp$(我当时就没想到$qwq$)。
$g[s]$表示状态为$s$的颜色满足条件(每个颜色属于$s$都已经内部连通)的最小代价。
转移的话,我们先设一个$now$表示的是所有颜色属于$s$的重要节点的编号的状态,那么$g[s]$就可以从$f[now][j]$转移过来($j$是$now$中的任意一个节点。)
这个就表示$s$代表的所有重要节点互相连通的方案数。
因为不同的颜色互相可以不连通,所以我们枚举$s$的子集$t$,用$g[t]+g[s-t]$转移到$s$即可。
时间复杂度$O(3^p\cdot n + 2^p \cdot m logn)$。
代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <queue>
- #define N 1100
- #define M 3010
- using namespace std;
- int head[N],to[M<<1],val[M<<1],nxt[M<<1],tot;
- int c[20],d[20],f[N][N],g[N];
- bool vis[N][N];
- priority_queue<pair<int,int> >q; // 堆优化Dij
- char *p1,*p2,buf[100000];
- #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
- int rd() {int x=0,f=1; char c=nc(); while(c<48) {if(c=='-') f=-1; c=nc();} while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}
- inline void add(int x,int y,int z) {to[++tot]=y; val[tot]=z; nxt[tot]=head[x]; head[x]=tot;}
- int main()
- {
- memset(f,0x3f,sizeof f);
- int n=rd(),m=rd(),p=rd();
- for(int i=1;i<=m;i++) {int x=rd(),y=rd(),z=rd(); add(x,y,z),add(y,x,z);}
- for(int i=1;i<=p;i++) c[i]=rd(),d[i]=rd(); // 分别记录节点颜色和编号
- for(int i=1;i<=p;i++) f[1<<(i-1)][d[i]]=0;
- int all=(1<<p)-1; // 表示所有重要节点的全集
- for(int i=1;i<=all;i++) // 斯坦纳树
- {
- for(int j=i;j;j=(j-1)&i)
- {
- for(int k=1;k<=n;k++)
- {
- f[i][k]=min(f[i][k],f[j][k]+f[i-j][k]);
- }
- }
- for(int j=1;j<=n;j++) q.push(make_pair(-f[i][j],j));
- while(!q.empty())
- {
- int x=q.top().second; q.pop();
- if(vis[i][x]) continue;
- vis[i][x]=true;
- for(int j=head[x];j;j=nxt[j]) if(f[i][to[j]]>f[i][x]+val[j])
- {
- f[i][to[j]]=f[i][x]+val[j];
- q.push(make_pair(-f[i][to[j]],to[j]));
- }
- }
- }
- memset(g,0x3f,sizeof g);
- for(int i=1;i<=all;i++) // 状压dp
- {
- int now=0; for(int j=1;j<=p;j++)
- {
- if(i&(1<<(c[j]-1)))
- {
- now|=(1<<(j-1));
- }
- }
- for(int j=1;j<=n;j++) g[i]=min(g[i],f[now][j]);
- for(int j=i;j;j=(j-1)&i) g[i]=min(g[i],g[j]+g[i-j]);
- }
- cout << g[all] << endl ;
- return 0;
- }
小结:这个斯坦纳树的题还是非常好的。不仅需要对斯坦纳树有点理解,对状压$dp$的使用还得比较灵活。
我当时就没想到后一步的状压$dp$。
[bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp的更多相关文章
- BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...
- 【bzoj4006】[JLOI2015]管道连接(斯坦纳树+dp)
题目链接 题意: 给出\(n\)个点,\(m\)条边,同时给出\(p\)个重要的点以及对应特征. 现在要选出一些边,问使得这\(p\)个所有特征相同的点相连,问最小代价. 思路: 斯坦纳树的应用场景一 ...
- bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...
- BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)
明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...
- 洛谷P3264 [JLOI2015]管道连接(斯坦纳树)
传送门 感觉对斯坦纳树还是有很多疑惑啊…… 等到时候noip没有爆零的话再回来填坑好了 //minamoto #include<iostream> #include<cstdio&g ...
- [JLOI2015]管道连接(斯坦纳树)
[Luogu3264] 原题解 多个频道,每个频道的关键点要求相互联通 详见代码,非常巧妙 #include<cstdio> #include<iostream> #inclu ...
- 【ZJOI2017 Round1练习&BZOJ4774】D3T2 road(斯坦纳树,状压DP)
题意: 对于边带权的无向图 G = (V, E),请选择一些边, 使得1<=i<=d,i号节点和 n − i + 1 号节点可以通过选中的边连通, 最小化选中的所有边的权值和. d< ...
- BZOJ_4006_[JLOI2015]管道连接_斯坦纳树
BZOJ_4006_[JLOI2015]管道连接_斯坦纳树 题意: 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰. 该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m ...
- BZOJ_2595_[Wc2008]游览计划_斯坦纳树
BZOJ_2595_[Wc2008]游览计划_斯坦纳树 题意: 分析: 斯坦纳树裸题,有几个需要注意的地方 给出矩阵,不用自己建图,但枚举子集转移时会算两遍,需要减去当前点的权值 方案记录比较麻烦,两 ...
随机推荐
- java实现斐波那契的两种方法
package com.ywx.count; /** * 斐波那契数列(地推方式要比递归方式的效率要高) * @author Vashon(yangwenxue) * date:20150320 */ ...
- Phalcon初认识
Phalcon以c扩展交付的全堆栈php开发框架 基本功能 低开销:低内存消耗和CPU相比传统的框架 MVC和HMVC:模块.组件.模型.视图和控制器 依赖注入:依赖注入和位置的服务和它的本身他们的容 ...
- js数组遍历的常用的几种方法以及差异和性能优化
<script type="text/javascript"> /*对比: 1.map速度比foreach快 2.map会返回一个新数组,不对原数组产生影响,forea ...
- 远程桌面连接windowsServer
1.win+R 打开windows运行工具栏: 2.输入 mstsc ,确定: 3.登录设置: 计算机:目标服务器ip地址:用户名:管理员或者用户的用户名,例如:administrator:密码:账户 ...
- 中间件及tomcat的内存溢出调优
主要是这三个选项的调整需要根据主机的内存配置 以及业务量的使用情况调节 -Xmx4g -Xms4g -Xmn2g xmx 与xms一般设置为一样 xmn大致设置为xmx xms的三分之一 可以使用 ...
- 进程池_Pool
当需要创建子进程数量不多的时候,可以直接利用multiprocessing中的Process动态生成多个进程 但是如果是成百甚至上千个任务,手动地创建它的工作量很大,此时就可以利用到multiproc ...
- EEPROM的存储大小
学习单片机时,常见的EEPROM如24C02的大小为2Kbit(有的也称2KB).这里的2KB到底能存储多少数据呢? 2KB中,B表示单位bit,K表示1024. 单片机编程中常用的数据类型为unsi ...
- 光猫&路由器网络配置
前期准备:电脑(工业电脑).网线.光猫.路由器 1.检查连接光猫后能否正常上网:把网线两头的水晶头,一头插在光猫上的千兆口,一头插在电脑(工业电脑)的网口上,看电脑能否正常上网: 可以正常上网:说明光 ...
- linux(Ubuntu/Centos) iproute 路由IP地址等命令集合,查看端口链接
原 linux(Ubuntu/Centos) iproute 路由IP地址等命令集合,查看端口链接 2017年03月20日 16:55:57 风来了- 阅读数:2291 标签: centoslinux ...
- RTMP协议研究
RTMP协议研究 1协议研究概述 协议设计和分析一直都是在工作遇到,正好在这里总结一下,说到协议,在这个网络的时代,没有人可以离开它了.他存在我们生活中的任何角落,只不过我们平时,并没有注意到它的存在 ...