【题目描述】

从未来过绍兴的小 D 有幸参加了Winter Camp 2008,他被这座历史名城的秀丽风景所吸引,强烈要求游览绍兴及其周边的所有景点。

主办者将绍兴划分为 N 行M 列(N×M)个方块,如下图(8×8)

景点含于方块内,且一个方块至多有一个景点。无景点的方块视为路。

为了保证安全与便利,主办方依据路况和治安状况,在非景点的一些方块内安排不同数量的志愿者;在景点内聘请导游(导游不是志愿者)。在选择旅游方案时,保证任意两个景点之间,存在一条路径,在这条路径所经过的每一个方块都有志愿者或者该方块为景点。既能满足选手们游览的需要,又能够让志愿者的总数最少。

例如,在上面的例子中,在每个没有景点的方块中填入一个数字,表示控制

该方块最少需要的志愿者数目:

图中用深色标出的方块区域就是一种可行的志愿者安排方案,一共需要20名志愿者。由图可见,两个相邻的景点是直接(有景点内的路)连通的(如沈园和八字桥)。

现在,希望你能够帮助主办方找到一种最好的安排方案。

【输入格式】

输入文件中 trip.in 中第一行有两个整数,N 和M,描述方块的数目。

接下来 N 行,每行有M 个非负整数,如果该整数为0,则该方块为一个景点;否则表示控制该方块至少需要的志愿者数目。相邻的整数用(若干个)空格隔开,行首行末也可能有多余的空格。

【输出格式】

输出一行一个整数,即最少的志愿者总数。

【样例输入】

4 4
0 1 1 0
2 5 5 1
1 5 5 1
0 1 1 0

【样例输出】

6

【提示】

样例方案:

其中红色方块安排了志愿者。

所有的 10 组数据中N, M ,以及景点数 K 的范围规定如下:

输入文件中的所有整数均不小于 0 且不超过2^16。

题解:

裸斯坦纳树,直接spfa+子集dp,暴力更新就行.

 #include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
typedef pair<int,int>par;
const int N=;
int n,m,INF,map[N][N],f[N][N][<<],S=,mx[]={,,,-},my[]={,-,,};
bool vis[N][N];
queue<par>q;
void spfa(int k){
for(int i=;i<=n;i++)for(int j=;j<=m;j++)
if(f[i][j][k]!=INF)
q.push(par(i,j));
int x,y,tx,ty;
while(!q.empty()){
x=q.front().first;y=q.front().second;q.pop();
for(int i=;i<;i++){
tx=x+mx[i];ty=y+my[i];
if(tx< || tx>n || ty< || ty>m)continue;
if(f[x][y][k]+map[tx][ty]<f[tx][ty][k]){
f[tx][ty][k]=f[x][y][k]+map[tx][ty];
if(!vis[tx][ty])q.push(par(tx,ty)),vis[tx][ty]=true;
}
}
vis[x][y]=false;
}
}
void work(){
scanf("%d%d",&n,&m);
memset(f,/,sizeof(f));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
scanf("%d",&map[i][j]);
if(!map[i][j])f[i][j][<<(S++)]=;
}
int states=(<<S)-;INF=f[][][];
for(int s=;s<=states;s++){
for(int i=;i<=n;i++)for(int j=;j<=m;j++)
for(int k=(k-)&s;k;k=(k-)&s){
if(f[i][j][k]+f[i][j][s-k]-map[i][j]<f[i][j][s])
f[i][j][s]=f[i][j][k]+f[i][j][s-k]-map[i][j];
}
spfa(s);
}
int ans=INF;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(f[i][j][states]<ans)
ans=f[i][j][states];
printf("%d\n",ans);
}
int main()
{
freopen("wc2008_trip.in","r",stdin);
freopen("wc2008_trip.out","w",stdout);
work();
return ;
}

[WC2008]游览计划的更多相关文章

  1. BZOJ_2595_[Wc2008]游览计划_斯坦纳树

    BZOJ_2595_[Wc2008]游览计划_斯坦纳树 题意: 分析: 斯坦纳树裸题,有几个需要注意的地方 给出矩阵,不用自己建图,但枚举子集转移时会算两遍,需要减去当前点的权值 方案记录比较麻烦,两 ...

  2. [WC2008]游览计划 解题报告

    [WC2008]游览计划 斯坦纳树板子题,其实就是状压dp 令\(dp_{i,s}\)表示任意点\(i\)联通关键点集合\(s\)的最小代价 然后有转移 \[ dp_{i,S}=\min_{T\in ...

  3. bzoj2595 / P4294 [WC2008]游览计划

    P4294 [WC2008]游览计划 斯坦纳树 斯坦纳树,是一种神奇的树.它支持在一个连通图上求包含若干个选定点的最小生成树. 前置算法:spfa+状压dp+dfs(大雾) 我们设$f[o][P]$为 ...

  4. 【BZOJ2595】 [Wc2008]游览计划

    BZOJ2595 [Wc2008]游览计划 Solution 考虑这是一个最小费用连通性的问题,既然大家都说这是什么斯坦纳树那就是的吧... 所以我们肯定可以这样设一个dp状态: \(dp_{i,j, ...

  5. 【BZOJ2595】[Wc2008]游览计划 斯坦纳树

    [BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...

  6. 【LG4294】[WC2008]游览计划

    [LG4294][WC2008]游览计划 题面 洛谷 bzoj 题解 斯坦纳树板子题. 斯坦纳树的总结先留个坑. 代码 #include <iostream> #include <c ...

  7. 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)

    2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1572  Solved: 7 ...

  8. BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*

    BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个 ...

  9. [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树

    游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...

  10. luogu P4294 [WC2008]游览计划

    LINK:游览计划 斯坦纳树例题. 斯坦纳树是这样一类问题:带权无向图上有K个关键点 求出包含这K个点的最小生成树. 也就是说 求最小生成树 但是 并不是整张图 仅限于K个点. 可以发现我们利用克鲁斯 ...

随机推荐

  1. android数据库持久化框架, ormlite框架,

    前言 Android中内置了SQLite,但是对于数据库操作这块,非常的麻烦.其实可以试用第3方的数据库持久化框架对之进行结构上调整, 摆脱了访问数据库操作的细节,不用再去写复杂的SQL语句.虽然这样 ...

  2. 我的PCB电路设计(一)

    我的制板规则 过孔大小:14/24mil-(12/22-28/50)  一般过孔没必要太大.如果电流较大可以适当增大过孔,或者多加几个过孔 线宽大小:小信号线8mil,大电流线不等按1A电流30mil ...

  3. 20170222==(MODBUS读取多个寄存器)

    MODBUS读取多个寄存器(功能码04) 为了简单我这里只用4个寄存器,当让你也可以用125个寄存器,但是最多也只能用125个寄存器的.每个寄存器有上面的表知道为一个字的大小即2个字节或者叫16比特位 ...

  4. Python内置函数(65)——staticmethod

    英文文档: staticmethod(function) Return a static method for function. A static method does not receive a ...

  5. Linux入门:增加用户,并赋予权限

    一.增加用户 1.增加用户,并指定主目录 # useradd –d /usr/sam -m sam此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录/usr/sam(/us ...

  6. hadoop2.6.0实践:004 启动伪分布式hadoop的进程

    [hadoop@LexiaofeiMaster hadoop-2.6.0]$ start-dfs.shStarting namenodes on [localhost]localhost: start ...

  7. 详解Ajax请求(四)——多个异步请求的执行顺序

    首先提出一个问题:点击页面上一个按钮发送两个ajax请求,其中一个请求会不会等待另一个请求执行完毕之后再执行? 答案是:不会,这两个异步请求会同时发送,至于执行的快与慢,要看响应的数据量的大小及后台逻 ...

  8. setInterval()使用时易疏忽的点

    举个例子: 一道题目 这两个程序的区别就在于我向setInterval的参数一function写入了参数.这就是导致运行结果不尽如人意的原因. setInterval()方法可以接收三个参数,此参数会 ...

  9. Python/Django-Web原理(一)

    Python/Django-Web原理(一) websocket webSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML规范中被引用为TCP连接,作为基于TCP的套接字AP ...

  10. 在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)

    在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)