【基于贪心的树型动态规划】【NOI2007】追捕盗贼
问题描述
魔法国度 Magic Land 里最近出现了一个大盗 Frank,他在 Magic Land 四处作案,专门窃取政府机关的机密文件(因而有人怀疑 Frank 是敌国派来的间谍)。
为了捉住 Frank,Magic Land 的安全局重拳出击!
Magic Land 由 N 个城市组成,并且这 N 个城市又由恰好 N-1 条公路彼此连接起来,使得任意两个城市间都可以通过若干条公路互达。从数据结构的角度我们也可以说,这 N 个城市和 N-1 条公路形成了一棵树。
例如,下图就是 Magic Land 的一个可能格局(4 个城市用数字编号,3 条公路用字母编号):
大盗 Frank 能够在公路上以任意速度移动。比方说,对于上图给出的格局,在 0.00001 秒钟内(或者任意短的一段时间内),Frank 就可以从城市 1 经过城市 2 到达城市 4,中间经过了两条公路。想要生擒 Frank 困难重重,所以安全局派出了经验丰富的警探,这些警探具有非凡的追捕才能:
1. 只要有警探和 Frank 同处一个城市,那么就能够立刻察觉到Frank,并且将其逮捕。
2. 虽然 Frank 可以在公路上以任意快的速度移动,但是如果有警探和 Frank 在同一条公路上相遇,那么警探也可以立刻察觉到 Frank 并将其逮捕。
安全局完全不知道 Frank 躲在哪个城市,或者正在哪条公路上移动,所以需要制定一个周密的抓捕计划,计划由若干步骤组成。在每一步中,可以做如下几件事中的一个:
1. 在某个城市空降一位警探。警探可以直接从指挥部空降到 Magic Land 的任意一个城市里。此操作记为“L x”,表示在编号为 x 的城市里空降一位警探。耗时 1 秒。
2. 把留在某个城市里的一位警探直接召回指挥部。以备在以后的步骤中再度空降到某个城市里。此操作记为“B x”。表示把编号为 x 的城市里的一位警探召回指挥部。耗时 1 秒。
3. 让待在城市 x 的一位警探沿着公路移动到城市 y,此操作记为“M x y”。耗时 1 秒。当然,前提是城市 x 和城市 y 之间有公路。如果在警探移动的过程中,大盗 Frank 也在同一条公路上,那么警探就抓捕到了Frank。
现在,由你来制定一套追捕计划,也就是给出若干个步骤,需要保证:无论大盗 Frank 一开始躲在哪儿,也无论 Frank 在整个过程中如何狡猾地移动(Frank大盗可能会窃取到追捕行动的计划书,所以他一定会想尽办法逃避),他一定会被缉拿归案。希望参与的警探越少越好,因为经验丰富的警探毕竟不多。
例如对于前面所给的那个图示格局,一个可行的计划如下:
1. L 2 在城市 2 空降一位警探。注意这一步完成之后,城市 2 里不会有 Frank,否则他将被捉住。
2. L 2 再在城市 2 空降一位警探。
3. M 2 1 让城市 2 的一位警探移动到城市 1。注意城市 2 里还留有另一位警探。这一步完成之后,城市 1 里不会有 Frank,公路 A 上也不会有 Frank。也就是说,假如 Frank 还没有被逮捕,那么他只能是在城市 3 或城市 4 里,或者公路 B 或公路 C 上。
4. B 1 召回城市 1 的一位警探。注意虽然召回了这位警探,但是由于我们始终留了一位警探在城市 2 把守,所以 Frank 仍然不可能跑到城市 1 或者是公路 A 上。
5. L 3 在城市 3 空降一位警探。注意这一步可以空降在此之前被召回的那位警探。这一步完成之后,城市 3 里不会有 Frank,否则他会被捉住。
6. M 3 2 让城市 3 里的一位警探移动到城市 2。这一步完成之后,如果 Frank 还没有被捉住,那他只能是在公路 C 上或者城市 4 里。注意这一步之后,城市 2 里有两位警探。
7. M 2 4 让城市 2 里的一位警探移动到城市 4。这一步完成之后,Frank 一定会被捉住,除非他根本就没来 Magic Land。这个计划总共需要 2 位警探的参与。可以证明:如果自始至终只有 1 名或者更少的警探参与,则 Frank 就会逍遥法外。
你的任务很简单:对于一个输入的 Magic Land 的格局,计算 S,也就是为了
追捕 Frank 至少需要投入多少位警探,并且给出相应的追捕计划步骤。
输入文件
输入文件给出了 Magic Land 的格局。
第一行一个整数 N,代表有 N 个城市,城市的编号是 1~N。
接下来 N-1 行,每行有两个用空格分开的整数 xi,yi,代表城市 xi,yi 之间有公路相连。保证 1≤xi,yi≤N
输出文件
向输出文件输出你所给出的追捕计划。
第一行请输出一个整数 S,代表追捕计划需要多少位警探。
第二行请输出一个整数 T,代表追捕计划总共有多少步。
接下来请输出 T 行,依次描述了追捕计划的每一步。每行必须是以下三种形式之一:
“L x”,其中 L 是大写字母,接着是一个空格,再接着是整数 x,代表在城市 x 空降一位警探。你必须保证 1≤x≤N。
“B x”,其中 B 是大写字母,接着是一个空格,再接着是整数 x,代表召回城市 x 的一位警探。你必须保证 1≤x≤N,且你的计划执行到这一步之前,城市 x 里面确实至少有一位警探。
“M x y”,其中 M 是大写字母,接着是一个空格,再接着是整数 x,再跟一个空格,最后一个是整数 y。代表让城市 x 的一位警探沿着公路移动到城市 y。你必须保证 1≤x, y≤N,且你的计划执行到这一步之前,城市 x 里面确实至少有一位警探,且城市 x, y 之前确实有公路。
必须保证输出的 S 确实等于追捕计划中所需要的警探数目。
样例输入
4
1 2
3 2
2 4
样例输出
2
7
L 2
L 2
M 2 1
B 1
L 3
M 3 2
M 2 4
评分标准
对于任何一个测试点:
如果输出的追捕计划不合法,或者整个追捕计划的步骤数 T 超过了 20000,或者追捕计划结束之后,不能保证捉住 Frank,则不能得分。
否则,用你输出的 S 和我们已知的标准答案 S*相比较:
1. 若 S<S*,则得到 120%的分。
2. 若 S=S*,则得到 100%的分。
3. 若 S*<S≤S*+2,则得到 60%的分。
4. 若 S*+2<S≤S*+4,则得到 40%的分。
5. 若 S*+4<S≤S*+8,则得到 20%的分。
6. 若 S>S +8,则得到 10%的分。
数据规模和约定
输入保证描述了一棵连通的 N 结点树,1≤N≤1 000。
虽然这是一个不完美的算法,但是也不失为一个优秀且性价比很高的算法。
首先要利用树的性质——每个点都是割点即每个度大于1的点(即除叶结点和只有一个子树的根结点以外的所有点)都可以把树分成若干个连通块。于是只要占住树根就可以递归进行将所有子树分别处理。
用f[u]表示占领整棵u为根的子树需要的最多警察数。
1) 若u为叶结点f[u] = 1。
2) 设val = max{f[v]} (v ∈ child(u))。
1˚ 若u的所有子节点中,有且只有一个v满足f[v] = val,则f[u] = val;
2˚ 若u的所有子节点中,有多个v满足f[v] = val,则f[u] = val + 1。
所以枚举所有的根,取一个f值最小的作为总根。(其它子节点由于时间的限制就只有不管了,这就是此算法得不到满分的原因。)
那么实现具体方案时,先将根控制住,再解决非关键链(只把其中一个f值最大的看作关键链,其他的都为非关键链),最后解决关键链(此时占据在根上的警察就可以移动了)。若遇到叶结点,则直接收回警察。
代码:
/**********************************\* @prob: NOI2007 catch ** @auth: Wang Junji ** @stat: 96分 ** @date: May. 30th, 2012 ** @memo: 基于贪心的树型动态规划 *
\**********************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>const int maxN = 1010, maxCMD = 100010;struct CMD
{int u, v; CMD() {} CMD(int u, int v): u(u), v(v) {}void print(){if (!u) printf("L %d", v);else if (!v) printf("B %d", u);else printf("M %d %d", u, v);return;}
} cmd[maxCMD], res[maxCMD];
struct Edge
{int v; Edge *next; Edge() {}Edge(int v, Edge *next): v(v), next(next) {}
} *edge[maxN]; int f[maxN], n, cnt, res_cnt, ans;void Dp(int u, int Last)
{int ch = 0, cnt_max = 0, Max = 0, v;for (Edge *p = edge[u]; p; p = p -> next) if ((v = p -> v) - Last){Dp(v, u);if (f[v] == Max) ++cnt_max;if (f[v] > Max) cnt_max = 1, Max = f[v];++ch;}f[u] = cnt_max > 1 ? Max + 1 : Max;if (!ch) f[u] = 1; return;
}void Dfs(int u, int Last, int D)
{int ch = 0, cnt_max = 0, Max = 0, pos = 0, v;for (Edge *p = edge[u]; p; p = p -> next) if ((v = p -> v) - Last){Dfs(v, u, 0);if (f[v] == Max) ++cnt_max;if (f[v] > Max) cnt_max = 1, Max = f[v], pos = v;++ch;}if (D){if (!ch) {cmd[cnt++] = CMD(u, 0); return;}for (Edge *p = edge[u]; p; p = p -> next)if ((v = p -> v) - Last && v - pos){cmd[cnt++] = CMD(0, u);cmd[cnt++] = CMD(u, v);Dfs(v, u, 1);}cmd[cnt++] = CMD(u, pos);Dfs(pos, u, 1);}f[u] = cnt_max > 1 ? Max + 1 : Max;if (!ch) f[u] = 1; return;
}int main()
{freopen("catch.in", "r", stdin);freopen("catch.out", "w", stdout);scanf("%d", &n);for (int i = 1; i < n; ++i){int u, v; scanf("%d%d", &u, &v);edge[u] = new Edge(v, edge[u]);edge[v] = new Edge(u, edge[v]);}int S = 1; ans = 0x3f3f3f3f;for (int s = 1; s < n + 1; ++s){Dp(s, 0);if (f[s] < ans) ans = f[s], S = s;}cmd[cnt = 0, cnt++] = CMD(0, S); Dfs(S, 0, 1);while (cnt && !cmd[cnt - 1].v) --cnt;printf("%d\n%d", ans, cnt);for (int i = 0; i < cnt; ++i) printf("\n"), cmd[i].print();return 0;
}
【基于贪心的树型动态规划】【NOI2007】追捕盗贼相关推荐
- POJ 2152 fire / SCU 2977 fire(树型动态规划)
POJ 2152 fire / SCU 2977 fire(树型动态规划) Description Country Z has N cities, which are numbered from 1 ...
- CJOJ 2171 火车站开饭店(树型动态规划)
CJOJ 2171 火车站开饭店(树型动态规划) Description 政府邀请了你在火车站开饭店,但不允许同时在两个相连的火车站开.任意两个火车站有且只有一条路径,每个火车站最多有 50 个和它相 ...
- 【算法•日更•第九期】树型动态规划详解:二叉苹果树
▎前置技能:动态规划&树 树型动态规划一听就知道是在树结构上使用的动态规划,那么不会树结构和动态规划怎么行?戳这里了解动态规划和树. ▎什么是树型动态规划? ☞『定义』 树形动态规划问题可以分 ...
- 【LeetCode笔记】337. 打家劫舍III(Java、树型动态规划)
文章目录 题目描述 思路 & 代码 更新版 题目描述 这年头当个小偷,都得会 dp 和二叉树了 和前面的 I & II 有点不同,这次直接换了数据结构,写树来了.(之后不会是图吧) 很 ...
- 提高篇 第五部分 动态规划 第2章 树型动态规划
例1 二叉苹果树 信息学奥赛一本通(C++版)在线评测系统 二叉苹果树_哔哩哔哩_bilibili 洛谷P2015 二叉苹果树 题目讲解 洛谷P2015 二叉苹果树 题目讲解_哔哩哔哩_bilibil ...
- 皇宫看守 树型动态规划
题目大意 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人 ...
- P2892 [NOI2007] 追捕盗贼
题目描述 小 Q 最近发现了一款新游戏,游戏的目标是从一个新手修炼成为武功高强的大侠.面对错综复杂的游戏世界,小 Q 要对他面临的每件事情做出谨慎的选择.例如,是否参加一个陌生人邀请的比武:同意或是拒 ...
- 【NOI2007】 追捕盗贼
题目描述 追捕盗贼 问题描述 魔法国度 Magic Land 里最近出现了一个大盗 Frank,他在 Magic Land 四处作 案,专门窃取政府机关的机密文件(因而有人怀疑 Frank 是敌国派来 ...
- 清华大学 陈晨 计算机,TNet基于树型结构集群工具软件通信协议.PDF
第2卷 第6期 444 中国科技论文在线 SCIENCEPAPER ONLINE 2007 年 6 月 TNet :基于树型结构的集群工具软件通信协议 陈 晨,陈文光,郑纬民 ( 清华大学计算机系, ...
最新文章
- 微信小程序万里目_4款万里挑一的微信小程序,每一个都是黑科技!
- 推荐!Sublime Text 最佳插件列表
- Terminal(终端) 在 OS X下如何快速调用
- Django---Model操作
- 解决写文档对于图片边框的强迫症
- 【Codeforces - 找不到题号】三元环计数(bitset优化,压位)
- 数据结构之基于Java的链接列表实现
- aov建立Java模拟,JAVA
- OpenStack手动制作CentOS 7 KVM镜像
- Python向已有数据的Excel表写入数据
- c++程序设计基础-类与对象:继承
- 打造综合娱乐性平台,TCL爱奇艺电视体验记
- SaaS模式、技术与案例详解——第16章 SaaS模式可行性分析
- Angular6笔记(4)
- 日语学习-五十音浊音
- 哆啦A梦?不好记!安利一下Prometheus这款开源的企业监控报警平台
- “大数据”如何接地气?
- 全国计算机等级考试二级教程——c语言程序设计》,格式为doc.,全国计算机等级考试二级C语言程序设计.doc...
- 2022年1月19日
- 实验4-3:RIPv2 路由汇总和认证