bzoj1402 Ticket to Ride 斯坦纳树 + 状压dp
给定\(n\)个点,\(m\)条边的带权无向图
选出一些边,使得\(4\)对点之间可达,询问权值最小为多少
\(n \leqslant 30, m \leqslant 1000\)
首先看数据范围,\(4\)对点,也就是\(8\)个点,很小
上斯坦纳树(局部最小生成树)
然而好像题目并不是斯坦纳树,可能是一些树拼到一起
那么就再做一个状压\(dp\)即可
复杂度\(O(3^8 * n + 2^8 * nm + 2^{12} * n)\)
#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int sid = 55;
const int eid = (1 << 9) - 1;
inline void cmin(int &a, int b) { if(a > b) a = b; }
int n, m, nc;
int U[sid], V[sid], cl[sid], ip[sid];
int f[sid][eid], E[sid][sid];
string s[55], sa, sb;
map <string, int> id;
int inq[sid];
queue <int> q;
void spfa(int S) {
memset(inq, 0, sizeof(inq));
for(int i = 1; i <= n; i ++) q.push(i);
while(!q.empty()) {
int id = q.front(); q.pop(); inq[id] = 0;
for(int j = 1; j <= n; j ++)
if(f[j][S] > f[id][S] + E[id][j]) {
f[j][S] = f[id][S] + E[id][j];
if(!inq[j]) q.push(j), inq[j] = 1;
}
}
}
void wish1() {
memset(f, 56, sizeof(f));
for(int i = 1; i <= n; i ++)
if(cl[i]) {
nc ++;
ip[i] = nc;
f[i][(1 << nc - 1)] = 0;
}
for(int S = 0; S <= (1 << nc) - 1; S ++) {
for(int i = 1; i <= n; i ++)
for(int T = S; T; T = (T - 1) & S)
cmin(f[i][S], f[i][T] + f[i][S ^ T]);
spfa(S);
}
}
int g[eid];
void wish2() {
memset(g, 56, sizeof(g)); g[0] = 0;
for(int s = 0; s <= (1 << 4) - 1; s ++)
for(int i = 1; i <= n; i ++)
for(int S = 0; S <= (1 << nc) - 1; S ++) {
int T = 0;
for(int k = 1; k <= 4; k ++)
if((S & (1 << ip[U[k]] - 1)) && (S & (1 << ip[V[k]] - 1)))
T |= (1 << k - 1);
cmin(g[s | T], g[s] + f[i][S]);
}
printf("%d\n", g[(1 << 4) - 1]);
}
int main() {
freopen("bzoj1402.in", "r", stdin);
freopen("bzoj1402.out", "w", stdout);
cin >> n >> m;
for(int i = 1; i <= n; i ++) {
cin >> s[i];
id[s[i]] = i;
}
memset(E, 56, sizeof(E));
for(int i = 1; i <= m; i ++) {
int u, v, w;
cin >> sa >> sb >> w;
u = id[sa]; v = id[sb];
cmin(E[u][v], w); E[v][u] = E[u][v];
}
for(int i = 1; i <= 4; i ++) {
int u, v;
cin >> sa >> sb;
u = id[sa]; v = id[sb];
U[i] = u; V[i] = v;
cl[u] = cl[v] = 1;
}
wish1(); wish2();
return 0;
}
bzoj1402 Ticket to Ride 斯坦纳树 + 状压dp的更多相关文章
- 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp
题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...
- bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...
- bzoj 4006 管道连接 —— 斯坦纳树+状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 用斯坦纳树求出所有关键点的各种连通情况的代价,把这个作为状压(压的是集合选择情况)的初 ...
- BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)
Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1171 Solved: 639[Submit][Status][Discuss] Descripti ...
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
- 绿色计算大赛决赛 第二阶段 消息传递(斯坦纳树 状压dp+spfa)
传送门 Description 作为公司老板的你手下有N个员工,其中有M个特殊员工.现在,你有一个消息需要传递给你的特殊员工.因为你的公司业务非常紧张,所以你和员工之间以及员工之间传递消息会造成损失. ...
- hdu4085 Peach Blossom Spring 斯坦纳树,状态dp
(1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s ...
- HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA
状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 当中k和l是对j的一个划分 依照边进行松弛 dp[i][j] ...
- 51nod 1673 树有几多愁——虚树+状压DP
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1673 建一个虚树. 一种贪心的想法是把较小的值填到叶子上,这样一个小值限制到的 ...
随机推荐
- Python练习-不知道弄个什么鬼
Alex大神,今天丢过来一个PDF,结果就成了这个样子! 1. 执行 Python 脚本的两种方式 交互方式: 命令行 文件方式: ...
- CCN与CDN区别
CCN与CDN区别 相同点: 1.针对目前互联网上存在问题,提出解决方案,让数据传输更快更稳定. 2.都均衡网络流量. 区别: 1.CDN是内容分发网络,是基于目前的TCP/IP体系结构的补充方法.C ...
- 2016.5.14——leetcode-HappyNumber,House Robber
leetcode:HappyNumber,House Robber 1.Happy Number 这个题中收获2点: 1.拿到题以后考虑特殊情况,代码中考虑1和4,或者说<6的情况,动手算下.( ...
- linux中set、unset、export、env、declare,readonly的区别以及用法
set命令显示当前shell的变量,包括当前用户的变量; env命令显示当前用户的变量; export命令显示当前导出成用户变量的shell变量. 每个shell有自己特有 ...
- JSON数据生成树——(四)
1.页面中准备树的div <div class="user_left_tree_info"> <div class="user_left_tree_in ...
- weblogica 启动managed server 不用每次输入密码
[weblogic@node2 AdminServer]$ pwd /home/weblogic/Oracle/Middleware/Oracle_Home/user_projects/domains ...
- 渗透测试===kali linux的安装
方法一: kali linux 安装在本地的vitural box 或者 wm ware中 方法二: 安装在移动硬盘或者储存卡中,插到电脑就能用
- python 元组分组并排序
# -*- coding: utf-8 -*- # @Time : 2018/8/31 14:32 # @Author : cxa # @File : glomtest.py # @Software: ...
- Fiddler是最强大最好用的Web调试工具
Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说,都有很大 ...
- python基础-类的封装
封装:类中封装了公有属性和方法,对象封装了私有属性的值 class F1: def __init__(self,n): self.N=n print('F') class F2: def __init ...