bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=4006
【题意】
给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的点都连通的最小费用。
【思路】
题目所求斯坦纳森林。
如果我们知道满足颜色集合S连通的最小值g[S],则有转移式:
G[S]=min{ g[s] , G[S’]+G[S-S’] }
则G[(1<<C)-1]即答案,G[S]定义为使得颜色集合S中所有相同颜色的点都连通的最小值。
这里的g[S],其实就是一棵包含S中所有颜色的斯坦纳树,即求一棵包含所有颜色在S中的点的斯坦纳树,我们设f[i][st]为在i点且包含点集为st的最小花费则有转移式:
f[i][st]=min{ f[i][st’]+f[i][st-st’] }
f[i][st]=min{ f[i’][st]+weight(i,i’) }
两次状压DP bingo。memset那里可以优化一下,懒得改了 =_=
【代码】
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 1e3+;
const int M = 4e3+;
const int P = ;
const int inf = 0xf0f0f0f; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
}
struct Edge { int v,w,nxt;
}e[M<<];
int en=,front[N];
void adde(int u,int v,int w)
{
e[++en]=(Edge){v,w,front[u]}; front[u]=en;
}
struct Node {
int c,w;
bool operator < (const Node& rhs) const {
return c<rhs.c;
}
}ns[P]; int n,m,K,cnt=;
int f[N][<<P],g[<<P]; queue<int> q; int inq[N]; void spfa(int sta)
{
while(!q.empty()) {
int u=q.front(); q.pop(); inq[u]=;
trav(u,i) {
int v=e[i].v;
if(f[v][sta]>f[u][sta]+e[i].w) {
f[v][sta]=f[u][sta]+e[i].w;
if(!inq[v])
inq[v]=,q.push(v);
}
}
}
}
int solve()
{
int all=<<cnt;
FOR(sta,,all-) {
FOR(i,,n) {
for(int s=(sta-)&sta;s;s=(s-)&sta)
f[i][sta]=min(f[i][sta],f[i][s]+f[i][sta-s]);
if(f[i][sta]!=inf) q.push(i),inq[i]=;
}
spfa(sta);
}
int ans=inf;
FOR(i,,n) ans=min(ans,f[i][all-]);
return ans;
} int main()
{
freopen("channel.in","r",stdin);
freopen("channel.out","w",stdout);
n=read(),m=read(),K=read();
FOR(i,,m) {
int u=read(),v=read(),w=read();
adde(u,v,w); adde(v,u,w);
}
FOR(i,,K) {
ns[i].c=read(),ns[i].w=read();
}
sort(ns+,ns+K+);
int C=;
FOR(i,,K) {
if(ns[i].c!=ns[i-].c) C++;
ns[i].c=C;
}
memset(g,0xf,sizeof(g));
int all=<<C;
FOR(sta,,all-) {
memset(f,0xf,sizeof(f));
cnt=; FOR(i,,K) if((<<ns[i].c-)&sta) f[ns[i].w][<<cnt++]=;
g[sta]=solve();
}
FOR(sta,,all-) {
for(int s=(sta-)&sta;s;s=(s-)&sta)
g[sta]=min(g[sta],g[s]+g[sta-s]);
}
printf("%d\n",g[all-]);
return ;
}
bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)的更多相关文章
- 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp
题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...
- BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)
Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1171 Solved: 639[Submit][Status][Discuss] Descripti ...
- bzoj 4006 管道连接 —— 斯坦纳树+状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 用斯坦纳树求出所有关键点的各种连通情况的代价,把这个作为状压(压的是集合选择情况)的初 ...
- bzoj 4006 [JLOI2015]管道连接——斯坦纳树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 除了模板,就是记录 ans[ s ] 表示 s 合法的最小代价.合法即保证 s 里同一 ...
- BZOJ4006 JLOI2015 管道连接(斯坦纳树生成森林)
4006: [JLOI2015]管道连接 Time Limit: 30 Sec Memory Limit: 128 MB Description 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的 ...
- BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...
- 【BZOJ4774/4006】修路/[JLOI2015]管道连接 斯坦纳树
[BZOJ4774]修路 Description 村子间的小路年久失修,为了保障村子之间的往来,法珞决定带领大家修路.对于边带权的无向图 G = (V, E),请选择一些边,使得1 <= i & ...
- 洛谷P3264 [JLOI2015]管道连接 (斯坦纳树)
题目链接 题目大意:有一张无向图,每条边有一定的花费,给出一些点集,让你从中选出一些边,用最小的花费将每个点集内的点相互连通,可以使用点集之外的点(如果需要的话). 算是斯坦纳树的入门题吧. 什么是斯 ...
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
随机推荐
- maven 环境搭建 Myeclipse配置
一:Maven的下载安装 准备工作: 1)安装环境 Windows xp 2)需安装JDK ,并配置环境变量(略) 3) Maven版本3.0.5 4)下载地址:http://mirror.bit.e ...
- PowerDesigner模型设计
原文:PowerDesigner模型设计 绪论 Sybase PowerDesigner(简称PD)是最强大的数据库建模工具,市场占有率第一,功能也确实十分强大,现在最新版本是15.1,已经支持最新的 ...
- 关于spring-mvc的InitBinder注解的参数
关于spring-mvc的InitBinder注解的参数 通过Spring-mvc的@InitBinder注释的方法可以对WebDataBinder做一些初始化操作.比如设置Validator. 我一 ...
- C++:运算符重载函数之"++"、"--"、"[ ]"、"=="的应用
5.2.5 "++"和"--"的重载 对于前缀方式++ob,可以用运算符函数重载为: ob.operator++() //成员函数重载 或 operator++ ...
- 常用的coco2d-x游戏开发工具(转)
物理编辑工具Physics Editing ToolsMekanimo 网址:http://www.mekanimo.net/PhysicsBench 网址:http://www.cocos2d-ip ...
- parseInt和valueOf
.parseInt和valueOf.split static int parseInt(String s) 将字符串参数作为有符号的十进制整数进行分析. static Integer valueOf( ...
- ASP.NET MVC 学习5、登陆页面改为SSO验证
单点登录(SSO,single sign-on)是一个会话或用户身份验证过程,用户只需要登录一次就可以访问所有相互信任的应用系统,二次登录时无需重新输入用户名和密码.简化账号登录过程并保护账号和密码安 ...
- SQL千万级数据设计和优化
1. 数据太多.放在一个表肯定不行. 比如月周期表.一个月1000万,一年就1.2亿,如此累计下去肯定不行的.所以都是基于一个周期数据一个表.甚至一个周期数据就要分几个分表.主要是考虑实际的数据量而定 ...
- Math.trunc
- 【C#学习笔记】检测进程是否存在并关闭
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...