Description

  

  传送门

  

  

  

  

  

Solution

  

  题目要求相同颜色的点必须在一个连通块中,但会有多个颜色同属一个连通块使得解更优的情况。

  

  想一想DP能否行得通:设\(g_i\)表示已考虑颜色状态为\(i\)时,最小合法方案的代价。

  

  首先,\(g_i\)可以有一个直观的初值:由颜色属于\(i\)的点构建的一棵最小生成树的边权和。(初始化)

  

​  接下来,如何考虑两部分颜色各自的连通块合起来作为最优解的情况?(两子集合并更新)

  

​  更新\(g_i\)时,我们枚举\(i\)的两个不相交子集\(s_1,s_2\)且\(s_1|s_2=i\),并用\(g_{s_1}+g_{s_2}\)来更新\(g_i\),即直接尝试将两个连通块取交。不需要担心两部分会有重复计算某一条边的情况,因为这是子集枚举DP,有边重复计算的转移自然不会成为最优转移,最优的转移一定会被枚举到(或者就是初值最优)。

  

​  以上两种方法并用,就可以顺利DP出\(g\)。

  

​  答案就是\(g_{all}\)。\(all\)是包含所有颜色的集合。

  

​  对于\(g\)的初值,直接用斯坦纳树计算所有关键点的不同组合的最小生成树即可。

  

  

  

Code

  

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int N=1005,M=3005,C=10,INF=1e9;
int n,m,p,col[N],tin[N][2],colst[C+1];
int idcnt,id[N],rep[C+1];
int clis[C+1],ccnt;
int f[N][1<<C],g[1<<C];
queue<int> q;
bool inq[N];
int h[N],tot;
struct Edge{int v,w,next;}e[M*2];
inline int bit(int i){return !i?0:(1<<(i-1));}
inline bool in(int st,int i){return (st>>(i-1))&1;}
inline void addEdge(int u,int v,int w){
e[++tot]=(Edge){v,w,h[u]}; h[u]=tot;
e[++tot]=(Edge){u,w,h[v]}; h[v]=tot;
}
void read(){
scanf("%d%d%d",&n,&m,&p);
for(int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
}
for(int i=1,c,u;i<=p;i++){
scanf("%d%d",&c,&u);// c ?
tin[i][0]=c; tin[i][1]=u;
clis[++ccnt]=c;
}
sort(clis+1,clis+1+ccnt);
ccnt=unique(clis+1,clis+1+ccnt)-clis-1;
for(int i=1,u,c;i<=p;i++){
c=lower_bound(clis+1,clis+1+ccnt,tin[i][0])-clis;
u=tin[i][1];
col[u]=c;
id[u]=++idcnt;
rep[c]=u;
colst[c]|=bit(id[u]);
}
}
void spfa(int st){
while(!q.empty()){
int u=q.front(); q.pop();
inq[u]=false;
for(int i=h[u],v;i;i=e[i].next){
v=e[i].v;
int ns=st|bit(id[v]);
if(f[u][st]+e[i].w<f[v][ns]){
f[v][ns]=f[u][st]+e[i].w;
if(!inq[v]){
inq[v]=true;
q.push(v);
}
}
}
}
}
void steinerTree(){
int all=1<<p;
for(int i=1;i<=n;i++){
for(int j=0;j<all;j++) f[i][j]=INF;
f[i][bit(id[i])]=0;
}
for(int j=1;j<all;j++){
for(int i=1;i<=n;i++)
if(!(id[i]&&!in(j,id[i]))){
for(int sub=(j-1)&j;sub;sub=(sub-1)&j){
int x=sub|bit(id[i]),y=(j^sub)|bit(id[i]);
if(f[i][x]+f[i][y]<f[i][j])
f[i][j]=f[i][x]+f[i][y];
}
if(f[i][j]!=INF)
q.push(i),inq[i]=true;
}
spfa(j);
}
}
void solve(){
int all=1<<ccnt;
for(int i=1;i<all;i++){
int st=0,rt=0;
for(int j=1;j<=ccnt;j++)
if(in(i,j))
st|=colst[j],rt=rep[j];
g[i]=f[rt][st];
for(int sub=(i-1)&i;sub;sub=(sub-1)&i)
g[i]=min(g[i],g[sub]+g[i^sub]);
}
printf("%d\n",g[all-1]);
}
int main(){
read();
steinerTree();
solve();
return 0;
}

【BZOJ4006】【JLOI2015】管道连接的更多相关文章

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

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

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

    4006: [JLOI2015]管道连接 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1020  Solved: 552[Submit][Statu ...

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

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

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

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

  5. BZOJ4006 [JLOI2015]管道连接

    裸的状压DP 令$f_S$表示包含颜色集合S的最小斯坦纳生成森林的值,于是有: $$f_S=\min\{f_S,f_s+f_{S-s}|s\subset S\}$$ 然后嘛...还是裸的斯坦纳树搞搞. ...

  6. BZOJ_4006_[JLOI2015]管道连接_斯坦纳树

    BZOJ_4006_[JLOI2015]管道连接_斯坦纳树 题意: 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰. 该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m ...

  7. luogu P3264 [JLOI2015]管道连接

    LINK:管道连接 一张无向图 有P个关键点 其中有K个集合 各个集合要在图中形成联通块 边有边权 求最小代价. 其实还是生成树问题 某个点要和某个点要在生成树中 类似这个意思. 可以发现 是斯坦纳树 ...

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

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

  9. 【bzoj4006】[JLOI2015]管道连接(斯坦纳树+dp)

    题目链接 题意: 给出\(n\)个点,\(m\)条边,同时给出\(p\)个重要的点以及对应特征. 现在要选出一些边,问使得这\(p\)个所有特征相同的点相连,问最小代价. 思路: 斯坦纳树的应用场景一 ...

  10. [JLOI2015]管道连接

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

随机推荐

  1. 《spark机器学习 第二版》 蔡立宇 分享 pdf下载

    链接:https://pan.baidu.com/s/15Y14eAnfj8zf5mXdixbVeQ 提取码:rkdt

  2. 关于几个与IO相关的重要概念

    1.读/写IO 读IO就是发指令从磁盘读取某段序号连续的扇区内容.指令一般是通知磁盘开始扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区个数,同时给出动作是读还是写.磁盘收到这条指令就会按照指令 ...

  3. php从入门到放弃系列-02.php基础语法

    php从入门到放弃系列-02.php基础语法 一.学习语法,从hello world开始 PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器&qu ...

  4. VGG——Very deep convolutional networks for large-scale image recognition

    1. 摘要 在使用非常小(3×3)的卷积核情况下,作者对逐渐增加网络的深度进行了全面的评估,通过设置网络层数达 16-19 层,最终效果取得了显著提升. 2. 介绍 近来,卷积神经网络在大规模图像识别 ...

  5. Android工程导入Unity3D(避坑版)

    最近与各种牛逼的项目管理软件打交道,比如SourceTree,要看英文版的才看得懂,中文反而不会用!... 这篇博客适合没怎么接触过安卓的小伙伴们,网上也有很多相关的教程,但是大多都没有具体的操作或则 ...

  6. [T-ARA][느낌 아니까][懂得那份感觉]

    歌词来源:http://music.163.com/#/song?id=27808771 作曲 : 박덕상/박현중 [作曲 : p/bag-ddeog-ssang-/p/ba-Kyeon-c/jung ...

  7. pycharm连接服务器

    python其他知识目录 1. pycharm当做xshell等远程工具,远程连接服务器步骤: 2.pycharm结合Linux服务器进行代码学习: 2.2使用pycharm远程在服务器上修改和执行代 ...

  8. 团队博客作业Week1 --- 团队成员简介

    团队博客作业Week1 团队作业1 我们团队是一个以功能团队模式组建而成的团队,我们总共有5位队员,分别是:李剑锋.陈谋.卢惠明.潘成鼎.仉伯龙. 中间的那位就是李剑锋,我们的PM(项目经理).性格热 ...

  9. 人and绩效and职业道德

    人行走在这个世界上 避免不了的是各种悲哀 人就像是一个茶几 上面放满了各种杯具 而要做的是要么把杯具打碎了咽下去,要么被杯具打晕 本布衣 躬耕于南阳 不求闻达于诸侯 每个人都可以选择自己的生活方式 或 ...

  10. SQL Server 无法连接到本地服务器

    未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接:     解决办法: 在服务中启动SQL Server (MSSQLSERVER)这个服务.