题目链接

题目描述

小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰。该部门有 n 个情报站,用 1 到 n 的整数编号。给出 m 对情报站 ui;vi 和费用 wi,表示情报站 ui 和 vi 之间可以花费 wi 单位资源建立通道。

如果一个情报站经过若干个建立好的通道可以到达另外一个情报站,那么这两个情报站就建立了通道连接。形式化地,若 ui 和 vi 建立了通道,那么它们建立了通道连接;若 ui 和 vi 均与 ti 建立了通道连接,那么 ui 和 vi 也建立了通道连接。

现在在所有的情报站中,有 p 个重要情报站,其中每个情报站有一个特定的频道。小铭铭面临的问题是,需要花费最少的资源,使得任意相同频道的情报站之间都建立通道连接。

Sol

首先要会斯坦那树。

其实只是一种解决一类状压dp的方法。

当我们需要进行有关联通性的状压 dp 时 , 只要求关键点连通且关键点较少 , 但是非关键点比较多的时候 , 可以用到斯坦那树。

其实是一类不要求所有点连通而只要求一部分点连通的 \(MST\) , 只能状压来求。

状压关键点的连通性 , 并确定一个点已经在树中 , 那么在不影响关键点的状态 , 也就是相同状态中可以用最短路来转移 , 而不同状态一般固定一个点 , 枚举子集然后合并。

通过最短路巧妙解决了非关键之间连边的决策。

但是这道题并不是要求所有关键点联通 , 而是要一些类关键点分别连通 , 不过这个也简单 , 我们最后状压一下所有种类之间的连通性再做一遍背包就行了。

我的代码常数太大,必须要开 O2 才能过..

code:

#include<bits/stdc++.h>
using namespace std;
#define Set(a,b) memset(a,b,sizeof(a))
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return ;
}
const int N=1021,M=3021;
const int MAXN=1<<10;
const int INF=2e9;
const int NN=13;
typedef long long ll;
struct pack{
int u,val;
pack(int _u=0,int _val=0){u=_u,val=_val;}
inline bool operator <(const pack B)const{
return val>B.val;
}
}Im[NN];
queue<int> Q;
bool vis[N];
int n,m,p;
struct edge{int to,next,w;}a[M<<1];
int head[N],cnt=0;
inline void add(int x,int y,int w){a[++cnt]=(edge){y,head[x],w};head[x]=cnt;}
int dis[N][MAXN],g[MAXN];
int id[N];
inline void SPFA(int S){
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int v,i=head[u];i;i=a[i].next){
v=a[i].to;
if(dis[v][S]==-1||dis[v][S]>dis[u][S]+a[i].w) {
dis[v][S]=dis[u][S]+a[i].w;
if(!vis[v]) Q.push(v),vis[v]=1;
}
}
vis[u]=0;
}
return;
}
int size[NN],R[NN],h=0,ful[NN];
inline int Calc(int S){int sta=0;for(int i=0;i<h;++i) if((S&ful[i])==ful[i]) sta|=1<<i;return sta;}
int main()
{
init(n),init(m),init(p);
int u,v,w;
for(int i=1;i<=m;++i) {
init(u),init(v),init(w);
add(u,v,w);add(v,u,w);
}
Set(id,-1);Set(dis,-1);
for(int i=1;i<=p;++i) {
init(w),init(u);
Im[i]=pack(u,w);
}sort(Im+1,Im+1+p);
int pre=0;int now=0;
for(int i=1;i<=p;++i) {
id[Im[i].u]=i-1;
if(Im[i].val!=Im[i+1].val) {
R[h]=i;size[h]=i-pre;
ful[h]=((1<<i)-1)^now;now|=ful[h];
pre=i;++h;
}
}
for(int i=1;i<=n;++i) {if(~id[i]) dis[i][1<<id[i]]=0;dis[i][0]=0;}
int Full=(1<<p)-1;Set(g,-1);
for(int S=0;S<=Full;++S){
int sta=Calc(S);
for(int i=1;i<=n;++i) {
vis[i]=0;
for(int T=(S-1)&S;T>0;T=(T-1)&S){
if(T<=0) break;
if((~dis[i][T])&&(~dis[i][S^T])) {if(dis[i][S]==-1||dis[i][S]>dis[i][T]+dis[i][S^T]) dis[i][S]=dis[i][T]+dis[i][S^T];}
}
if(dis[i][S]!=-1) {
Q.push(i);vis[i]=1;
if((g[sta]==-1||g[sta]>dis[i][S])) g[sta]=dis[i][S];
}
}SPFA(S);
}int full=(1<<h)-1;
for(int S=0;S<=full;++S){
for(int T=(S-1)&S;T>0;T=(T-1)&S){
if(T<=0) break;if(g[T]==-1||g[S^T]==-1) continue;
if(g[S]==-1||g[S]>g[T]+g[S^T]) g[S]=g[T]+g[T^S];
}
}
cout<<g[full]<<endl;
}

【LuoguP3264】[JLOI2015] 管道连接(斯坦那树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 用Vue来实现音乐播放器(四十):歌单详情页布局以及Vuex实现路由数据通讯

    1.歌单详情页是推荐页面的二级路由页面 将推荐页面歌单的数据传到歌曲详情页面  利用vuex 1.首先在state下定义一个歌单对象 disc{} 2.在mutaions-types中  定义一个别名 ...

  2. [VBA]斐波那契数列

    Sub 斐波那契()Dim arrFor i = 3 To 100Cells(1, 1) = 0Cells(2, 1) = 1Cells(i, 1) = Cells(i - 1, 1) + Cells ...

  3. linux系统查找大文件脚本

    每次遇到服务器磁盘满,都会很苦恼,但有了下面两种方法就可以轻松找到机器中的大文件了, 第一种:du -sh du -sh 当前目录下个文件或目录的大小: du -sh * 显示前10个占用空间最大的文 ...

  4. 每次进步一点点——linux expect 使用

    1. 介绍 expect是建立在tcl(参见:Tcl/Tk快速入门 )基础上的一个工具,它可以让一些需要交互的任务自动化地完成.相当于模拟了用户和命令行的交互操作. 一个具体的场景:远程登陆服务器,并 ...

  5. mysql数据库自带数据库介绍

    show databases:查看mysql自带数据库有information_schema,mysql, performance_schema, test information_schema数据库 ...

  6. DG on Windows 10 S: 执行任意代码

    DG on Windows 10 S: 执行任意代码 windows 10 S版本是什么鬼? 众所周知,我们使用的是windows 10企业版 LTSC.更准确一点,CMD运行winver,我的版本是 ...

  7. linux/linux学习笔记-初识linux(mooc)

    一.linux简介 linux版本:内核版本和发行版本 linux企业应用: 1.基于linux的企业服务器 2.linux在嵌入式领域应用 android底层Linux : ios底层unix li ...

  8. Web安全测试中常见逻辑漏洞解析(实战篇)

    Web安全测试中常见逻辑漏洞解析(实战篇) 简要: 越权漏洞是比较常见的漏洞类型,越权漏洞可以理解为,一个正常的用户A通常只能够对自己的一些信息进行增删改查,但是由于程序员的一时疏忽,对信息进行增删改 ...

  9. MySQL8 clone plugin

    安装MySQl8.0.17 下载 MySQL8.0.17 二进制版本 https://dev.mysql.com/downloads/mysql/ 解压,修改权限 -linux-glibc2.-x86 ...

  10. vue axios应用

    编写小的demo应用axios异步请求. 效果图示: 功能: 用户在输入框中输入信息进行搜索,并搜索状态随之改变(四种状态). 项目目录: 代码: 1.index.html <!DOCTYPE ...