BZOJ2595(状压dp)
要点
- 设\(f[i][j][k]\)为经过点\((i,j)\)且包含点集\(k\)的最小代价,其中k是指景点集合的枚举。
- 考虑有两种情况:1.点\((i,j)\)作为关键点连接了两个子集时\(f[i][j][k]\)可以得到最小,有\(f[i][j][k]=f[i][j][k_1]+f[i][j][k_2]-a[i][j],\ k_1|k_2=k\);2.点\((i,j)\)作为主干道发展出来的枝叶时\(f[i][j][k]\)可以得到最小,那么它是它的邻居发展过来的,spfa跑一下即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int xx[] = {0, 0, -1, 1};
const int yy[] = {1, -1, 0, 0};
int N, M, K, a[11][11];
int f[11][11][1 << 11], pre[11][11][1 << 11][3], vis[11][11];
queue< pair<int, int> > Q;
void dfs(int i, int j, int U) {
if (!U) return;
vis[i][j] = 1;
int a = pre[i][j][U][0], b = pre[i][j][U][1], c = pre[i][j][U][2];
dfs(a, b, c);
if (i == a && j == b) dfs(a, b, c ^ U);
}
void output() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++)
if (!a[i][j]) putchar('x');
else if (vis[i][j]) putchar('o');
else putchar('_');
puts("");
}
}
int main() {
scanf("%d %d", &N, &M);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) {
for (int k = 0; k < (1 << 10); k++) {
f[i][j][k] = inf;
}
scanf("%d", &a[i][j]);
if (!a[i][j]) {
f[i][j][1 << (K++)] = 0;
}
}
for (int U = 1; U < (1 << K); U++) {
memset(vis, 0, sizeof vis);
//作为枝干的转移
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) {
for (int k = U & (U - 1); k; k = U & (k - 1)) {//枚举二进制真子集
int tmp = f[i][j][k] + f[i][j][k ^ U] - a[i][j];
if (tmp < f[i][j][U]) {
f[i][j][U] = tmp;
pre[i][j][U][0] = i;
pre[i][j][U][1] = j;
pre[i][j][U][2] = k;
}
}
if (f[i][j][U] < inf) Q.push({i, j}), vis[i][j] = 1;
}
//作为树枝的转移
while (Q.size()) {
int x = Q.front().first, y = Q.front().second; Q.pop();
vis[x][y] = 0;
for (int t = 0; t < 4; t++) {
int nx = x + xx[t], ny = y + yy[t];
if (nx < 1 || nx > N || ny < 1 || ny > M) continue;
if (f[nx][ny][U] > f[x][y][U] + a[nx][ny]) {
f[nx][ny][U] = f[x][y][U] + a[nx][ny];
pre[nx][ny][U][0] = x;
pre[nx][ny][U][1] = y;
pre[nx][ny][U][2] = U;
if (!vis[nx][ny]) Q.push({nx, ny}), vis[nx][ny] = 1;
}
}
}
}
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
if (!a[i][j]) {
memset(vis, 0, sizeof vis);
dfs(i, j, (1 << K) - 1);
printf("%d\n", f[i][j][(1 << K) - 1]);
output();
return 0;
}
}
BZOJ2595(状压dp)的更多相关文章
- BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*
BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...
- 【bzoj4006】[JLOI2015]管道连接 斯坦纳树+状压dp
题目描述 给出一张 $n$ 个点 $m$ 条边的无向图和 $p$ 个特殊点,每个特殊点有一个颜色.要求选出若干条边,使得颜色相同的特殊点在同一个连通块内.输出最小边权和. 输入 第一行包含三个整数 n ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
- HDU 1074 Doing Homework (状压dp)
题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...
- 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP
[BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...
随机推荐
- Android SDK中 tools 目录下的工具介绍
Android SDK包含了各种各样的定制工具,简介如下: Android模拟器(Android Emulator )它是在你的计算机上运行的一个虚拟移动设备.你可以使用模拟器来在一个实际的Andro ...
- 按钮滚动到指定位置(JS)
function intval(v) { v = parseInt(v); return isNaN(v) ? 0 : v; } function getPos(e) { var l = 0; var ...
- CI框架上传csv文件
今天遇到在用CI框架上传csv文件时报错问题: The filetype you are attempting to upload is not allowed. 是类型不允许,想到CI框架的conf ...
- NOIP 2016【蚯蚓】
好吧,我承认我是个智障-- 这道题一眼看上去就是个堆,然而实际上有单调性. 注意到,如果 \(q = 0\) 的话,将蚯蚓的左右两边分开丢进两个队列中,则两个队列都是单调不增的,因为每次取出的蚯蚓长度 ...
- OpenCV——PS滤镜算法之Spherize 球面化(凸出效果)
// define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...
- 【LeetCode】026. Remove Duplicates from Sorted Array
题目: Given a sorted array, remove the duplicates in place such that each element appear only once and ...
- RT-Thread OS的启动流程
1.RT进入main之前, SystemInit函数初始化时钟. 2.main函数位于startup.c文件中.进行两个工作 系统开始前,rt_hw_interrupt_disable关闭所有中断. ...
- JSP的优势 和劣势 与php的比较
一 jsp的 优势 与劣势 由于JSP页面的内置脚本语言是基于Java编程语言的,而且所有的JSP页面都被编译成为Java Servlet,JSP页面就具有Java技术的所有好处,包括健壮的存储管理和 ...
- [CentOS] 结合Nginx部署DotNetCore的demo项目【转载】
部署前准备 1.VisualStudio2017+.netcore2.0SDK 2.Centos7.2 3.SecureCRT,Xftp(根据自己喜好) 创建WebApi项目 修改Program.cs ...
- java枚举类型的优势在哪里?--一个实例
最近在做一个项目,其中涉及到一组操作,命名为: 1. "add"; 2. "logicDel" 3. "physicDel" 4. &quo ...