[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]游览计划_斯坦纳树 题意: 分析: 斯坦纳树裸题,有几个需要注意的地方 给出矩阵,不用自己建图,但枚举子集转移时会算两遍,需要减去当前点的权值 方案记录比较麻烦,两 ...
随机推荐
- 7-Java-C(骰子游戏)
题目描述: 我们来玩一个游戏. 同时掷出3个普通骰子(6个面上的数字分别是1~6). 如果其中一个骰子上的数字等于另外两个的和,你就赢了. 下面的程序计算出你能获胜的精确概率(以既约分数表示) pub ...
- Hbase数据库简介
Hbase是基于Hadoop下分布式存储 数据库,列式存储.(https://www.imooc.com/video/17202) 动态的增加列,不像关系数据库需要提前定义好列. 关系数据库 ...
- PHP21 MVC
学习目标 MVC设计模式 单一入口机制 MVC的实现 MVC设计模式 Model(模型) 是应用程序中用于处理应用程序数据逻辑的部分.通常模型对象负责在数据库中存取数据. View(视图) 是应用程序 ...
- _vimrc配置
set nocompatible set encoding=utf8 set guioptions-=T set number set guifont=consolas:h12 source $VIM ...
- 错误的语法:"create view必须是批处理中仅有的语句"
编写脚本提示: 错误的语法:"create view必须是批处理中仅有的语句" FROM sys.views WHERE name = 'v_CS_UserRoleNames' ) ...
- Linux基础学习-RHEL7.4之YUM更换CentOS源
1.配置YUM本地源 1.挂载镜像 [root@qdlinux ~]# mount /dev/cdrom /mnt 2.查看是否挂载成功 [root@qdlinux ~]# df -h Filesys ...
- 条款30:透彻了解inline的里里外外(understand the ins and outs of inlining)
NOTE: 1.将大多数inline限制在小型 被频繁调用的函数身上.这可使日后的调试过程和二进制升级(binary upgradability)更容易,也可使潜在的代码膨胀问题最小化, 使程序的速度 ...
- htmlpurifier的使用
什么是htmlpurifier?? HTML Purifier是一个可以用来移除所有恶意代码(XSS),而且还能确保你的页面遵循W3C的标准规范的PHP类库. 在php里解决XSS最简单的方法是使用h ...
- Django-Ajax组件
Ajax Ajax简介 AJAX(Asynchronous Javascript And XML),翻译成中文为"异步Javascript和XML".即使用Javascript语言 ...
- shiro框架的四中权限控制方式
https://www.cnblogs.com/cocosili/p/7103025.html 一.在自定义的realm中进行权限控制 在applicationContext.xml文件中添加 /a ...