明显是一道斯坦纳树的题。

然而这题只需要属性相同的点互相连接。

我们还是照常先套路求出\(ans[s]\)。

然后对\(ans[s]\)做子集DP即可。

具体看代码。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=1e9;
const int N=1111;
const int M=3333;
struct edge{
int to,nxt,w;
}e[M*2];
int cnt,head[N];
void add_edge(int u,int v,int w){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
e[cnt].w=w;
head[u]=cnt;
}
struct node{
int id,w;
node(int idd=0,int ww=0){
id=idd,w=ww;
}
};
struct point{
int k,id;
}c[N];
bool operator <(node a,node b){
return a.w>b.w;
}
priority_queue<node> q;
bool vis[N];
int dp[N][N];
void dij(int x){
memset(vis,0,sizeof(vis));
while(!q.empty()){
node uu=q.top();
q.pop();
int u=uu.id;
if(vis[u])continue;vis[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(dp[x][v]>dp[x][u]+e[i].w){
dp[x][v]=dp[x][u]+e[i].w;
q.push(node(v,dp[x][v]));
}
}
}
}
int a[15],num[15];
int n,m,k,tot,ans[N];
bool check(int s){
for (int i=1;i<=k;++i) a[i]=0;
for (int i=1;i<=k;++i)
if (s&(1<<(i-1))) a[c[i].k]++;
for (int i=1;i<=k;++i) if (a[i]&&a[i]!=num[i]) return false;
return true;
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int main(){
n=read(),m=read(),k=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add_edge(u,v,w);add_edge(v,u,w);
}
tot=(1<<k)-1;
for(int i=0;i<=tot;i++)
for(int j=1;j<=n;j++)
dp[i][j]=INF;
for(int i=1;i<=k;i++){
c[i].k=read(),c[i].id=read();
num[c[i].k]++;
}
for(int i=1;i<=k;i++)dp[1<<i-1][c[i].id]=0;
for(int t=0;t<=tot;t++){
for(int i=1;i<=n;i++)
for(int j=t;j;j=(j-1)&t)
dp[t][i]=min(dp[t][i],dp[j][i]+dp[t^j][i]);
for(int i=1;i<=n;i++)if(dp[t][i]!=INF)q.push(node(i,dp[t][i]));
dij(t);
}
for(int i=0;i<=tot;i++){
ans[i]=INF;
for(int j=1;j<=n;j++)
ans[i]=min(ans[i],dp[i][j]);
}
for(int i=0;i<=tot;i++)
if(check(i))
for(int j=i;j;j=(j-1)&i)
if(check(j))
ans[i]=min(ans[i],ans[j]+ans[j^i]);
printf("%d",ans[tot]);
return 0;
}

BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...

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

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

随机推荐

  1. vue组件通信,点击传值,动态传值(父传子,子传父)

    转载:https://blog.csdn.net/xr510002594/article/details/83304141 一.父组件传子组件,核心--props 在这里触发 handleClick ...

  2. [bzoj3505 Cqoi2014] 数三角形 (容斥+数学)

    传送门 Description 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形. 注意三角形的三点不能共线. Input 输入一行,包含两个空格分隔的正 ...

  3. 洛谷—— P1074 靶形数独

    https://www.luogu.org/problem/show?pid=1074 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但 ...

  4. shell脚本监测文件变化

    1. 我使用过的Linux命令之du - 查看文件的磁盘空间占用情况 用途说明 du命令是用来查看磁盘空间占用情况的,在Linux系统维护时常会用到,并且通常与df命令搭配使用.首先使用df看一下各个 ...

  5. Linux用户管理案例(第二版)

    批量添加用户 1.按照/etc/passwd文件格式编写用户信息文件users.info xiaofang01::1001:503::/home/xiaofang01:/bin/bash  #注意不能 ...

  6. validate命令---rman进行备份和回复的验证

    rman作为oracle备份与恢复工具,为我们提供了强大的功能.当中包含对数据文件的物理和逻辑检測以及备份文件的有效性检測. 首先.来看一下rman对数据文件的检測. 我们知道,rman在备份数据时, ...

  7. Chisel Tutorial(一)——Chisel介绍

    Chisel是由伯克利大学公布的一种开源硬件构建语言,建立在Scala语言之上,是Scala特定领域语言的一个应用,具有高度參数化的生成器(highly parameterized generator ...

  8. 浅析Context Class Loader

    浅析Context Class Loader 2010-05-11 16:58:49 分类: Java 转载自 薛笛的专栏http://blog.csdn.net/kabini/archive/200 ...

  9. 1、libgdx简单介绍

    Libgdx 是一个跨平台和可视化的的开发框架.它当前支持Windows.Linux,Mac OS X.Android,IOS和HTML5作为目标平台. Libgdx同意你一次编写代码不经改动部署到多 ...

  10. Android图文混排-实现EditText图文混合插入上传

    前段时间做了一个Android会议管理系统,项目需求涉及到EditText的图文混排,如图: 在上图的"会议详情"中.须要支持文本和图片的混合插入,下图演示输入的演示样例: 当会议 ...