bzoj 2595 斯坦纳树
题目大意:
选定一些格子保证景点对应的格子通过这些格子连通,保证选定的所有格子对应的权值和最小
这是相当于理解为将所有点形成的最小生成树
这里点的个数很少,所以可以对每一个点进行状态压缩
f[st][i]表示连通性至少为st,且经过i点的最小距离
方程1.f[st][i] = Min{f[s][i] + f[st - s][i]}(s为st的子集)
方程2.f[st][i] = Min{f[st][j] + w(i,j)}(i,j之间有边相连)
那么可以看出来大的状态总是跟小的状态有关,那么总是先求出小的状态集合
利用spfa求解所有状态对应的点跑最短路对其他格点进行松弛
我到现在也不知道为什么这样写效率会高
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef pair<int,int> pii;
#define N 11
const int MAXN=<<N;
const int INF = 0x3f3f3f3f;
int n , m ; struct Node{
int x , y , s;
Node(){}
Node(int x , int y , int s):x(x),y(y),s(s){}
};
Node pre[N][N][MAXN];//用于回溯找上一个节点 int w[N][N] , dp[N][N][MAXN] , dir[][]={{,},{,-},{,},{-,}};
bool vis[N][N] , flag[N][N];
queue<pii> que; bool ok(int x , int y){return x>=&&x<=n&&y>=&&y<=m;} void spfa(int state)
{
while(!que.empty()){
pii u = que.front();
que.pop();
int x = u.first , y = u.second;
vis[x][y] = false;
for(int i= ; i< ; i++){
int xx = x+dir[i][] , yy = y+dir[i][];
if(!ok(xx,yy)) continue;
if(dp[xx][yy][state]>dp[x][y][state]+w[xx][yy]){
dp[xx][yy][state]=dp[x][y][state]+w[xx][yy];
pre[xx][yy][state] = Node(x , y , state);
if(!vis[xx][yy]) que.push(make_pair(xx , yy));
}
}
}
} void huisu(int x , int y , int s)
{
flag[x][y] = true;
if(pre[x][y][s].s == ) return;
huisu(pre[x][y][s].x , pre[x][y][s].y , pre[x][y][s].s);
if(pre[x][y][s].x==x && pre[x][y][s].y==y) huisu(pre[x][y][s].x , pre[x][y][s].y , s-pre[x][y][s].s);
} void print()
{
for(int i= ; i<=n ; i++){
for(int j= ; j<=m ; j++)
if(!w[i][j]) printf("x");
else if(flag[i][j]) printf("o");
else printf("_");
puts("");
}
} int main()
{
// freopen("in.txt" , "r" , stdin);
while(~scanf("%d%d" , &n , &m))
{
int num = ;
memset(dp , 0x3f , sizeof(dp));
memset(pre , , sizeof(pre));
for(int i= ; i<=n ; i++){
for(int j= ; j<=m ; j++){
scanf("%d" , &w[i][j]);
if(!w[i][j]){
dp[i][j][<<num] = ;
num++;
}
}
}
int ALL_STATE = <<num;
for(int k= ; k<ALL_STATE ; k++){
for(int i= ; i<=n ; i++){
for(int j= ; j<=m ; j++){
for(int s=(k-)&k ; s ; s=(s-)&k){
int tmps = k-s;
if(dp[i][j][k]>dp[i][j][s]+dp[i][j][tmps]-w[i][j]){
dp[i][j][k] = dp[i][j][s]+dp[i][j][tmps]-w[i][j];
pre[i][j][k] = Node(i , j , s);
}
}
if(dp[i][j][k]<INF) que.push(make_pair(i , j)) , vis[i][j]=true;
}
}
spfa(k);
}
memset(flag , , sizeof(flag));
for(int i= ; i<=n ; i++)
for(int j= ; j<=m ; j++){
if(!w[i][j]){
cout<<dp[i][j][ALL_STATE-]<<endl;
huisu(i , j , ALL_STATE-);
print();
return ;
}
} }
return ;
}
bzoj 2595 斯坦纳树的更多相关文章
- BZOJ 2595 斯坦那树
很久以前就想做,后来弃坑了. 最近又在群里有人问了类似的问题,艾老师说是斯坦纳树(%%%) 就是状压DP,然后用Spfa对状态进行转移. #include <iostream> #incl ...
- bzoj 2595 [Wc2008]游览计划(斯坦纳树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...
- 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)
2595: [Wc2008]游览计划 Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 1572 Solved: 7 ...
- BZOJ 2595: [Wc2008]游览计划 [DP 状压 斯坦纳树 spfa]【学习笔记】
传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Stein ...
- BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树
[题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...
- BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...
- 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 用斯坦纳树求出所有关键点的各种连通情况的代价,把这个作为状压(压的是集合选择情况)的初 ...
- BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
腊鸡题目,实在卡不过去. (改了一下午) 就是裸的斯坦纳树的题目,一方面合并子集,另一方面SPFA迭代求解. 优化了许多地方,甚至基数排序都写了. 还是T到死,不打算改了,就这样吧 #include ...
随机推荐
- Android星星评分控件RatingBar的使用
在Android的开发中,有一个叫做评分控件RatingBar,我们可以使用该控件做等级划分.评分等作用,星星形状显示,也可以半星级别,我们来看一下评分控件如何使用. 布局文件中定义控件以及属性,这里 ...
- UML中类之间的几种关系
类之间可能存在以下几种关系:关联(association).依赖(dependency).聚合(Aggregation,也有的称聚集).组合(Composition).泛化(generalizatio ...
- Android_SDK的常用命令
一.配置环境变量 要想使用这些命令,就必须先配置环境变量. 将android-sdk-windows目录下的platform-tools目录和tools目录配置到path环境变量中 二.adb命令 ...
- Maven打包遇到的一些问题(zhuan)
http://qqbwww.iteye.com/blog/2042307 **************************************** #Maven打包遇到的一些问题 ## 1.将 ...
- OpenGL的glViewport视口变换函数详解[转]
调用glViewPort函数来决定视见区域,告诉OpenGL应把渲染之后的图形绘制在窗体的哪个部位.当视见区域是整个窗体时,OpenGL将把渲染结果绘制到整个窗口. void glViewPort(G ...
- python语法笔记(五)
1.python内存管理 (1)对象内存使用 &nsbp;&nsbp;&nsbp;&nsbp;在python中通过执行内建函数 id(obj) 可以获得对象obj在内存 ...
- python语法笔记(二)
1. 循环对象 循环对象是一类特殊的对象,它包含一个next()方法(在python3中是 __next__()方法),该方法的目的是进行到下一个结果,而在结束一系列结果之后,举出 StopItera ...
- PHP 安全相关 简单知识
概要: 1.php一些安全配置 (1)关闭php提示错误功能 (2)关闭一些“坏功能” (3)严格配置文件权限. 2.严格的数据验证,你的用户不全是“好”人 2.1为了确保程序的安全性,健壮性,数据验 ...
- B2车
晚上10点之后,杭州快速公交B2的司机,把2节车厢,开的像是跑车一样,每次启动都是弹射出去的,好像是在报复白天蜗牛般的速度.真乃是见神杀神,见佛杀佛.
- Mybatis 学习-1
本次MyBatis基础实例教程主要讲述MyBatis在项目中的配置方法,实体对象的关系映射.关联关系,以及如何实现一个BaseDao的功能 实例数据库的表结构 CREATE TABLE `blog_u ...