题意

有一个 \(N\) 个点, \(M\) 条边的有向图, 初始有一个机器人在 \(1\) 号点. 每个时刻, 这个机器人会随机选择一条从该点出发地边并通过.当机器人到达点 \(N\) 时, 它就会自动关闭.

然而这个机器人如果在某个时刻到达自己曾经到过的点的话, 它就会爆炸. 因此, 你决定对机器人实施一些命令, 让它在某些时候按照规定的边走, 而非随机选择.

问对机器人最少使用多少条命令可以让它安全到达点 \(N\) .

\(N, M \le 10^6\)

题解

十分巧妙的一道好题~

首先可以无视掉 “不能到达曾经到过的点” 的限制, 因为最优答案一定不会存在这种情况.

因为到达曾经到过的点,你至少要付出更多代价才能回到这个点,所以绝对不优。

然后我们就可以考虑一个 \(dp\) 了,令 \(dp_u\) 为 \(u\) 走到 \(T\) 需要的最少命令。

那么显然有一个转移:

\[dp_u=\min_{(u, v)} \{\min\{dp_v\}+1,\max\{dp_v\}\}
\]

这个意义是很明显的,就不解释了。

这个本质上是个 \(0 / 1\) BFS 问题,用个双端队列维护就行了,\(0\) 加到队首, \(1\) 加到队尾就行了。

具体实现的时候,我们只有在第一次到达这个点的时候会更新 \(\min\{dp_v\}+1\) ,因为是 BFS 最早到的肯定是距离较小的点。

也就是队列中的点 \(dis\) 单调不下降。

然后最后一次到达这个点才会更新 \(\max\{dp_v\}\) ,同样这是 BFS 最晚到的点。

每个点我们只会访问一次,所以最后一次到达就是它入度减少到 \(0\) 的时候。

复杂度是 \(O(n + m)\) 的。

总结

对于一类图上有关 \(dp\) 的 \(\min,\max\) 问题能考虑 BFS 队列的 \(dis\) 单调不下降的性质来转移。

代码

记得要把边反向,以及入度也要反向。


#include <bits/stdc++.h> #define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__) using namespace std; inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x * fh;
} void File() {
#ifdef zjp_shadow
freopen ("D.in", "r", stdin);
freopen ("D.out", "w", stdout);
#endif
} const int N = 1e6 + 1e3; int n, m, deg[N], dp[N]; vector<int> G[N]; int S, T; bitset<N> vis;
void Bfs() {
Set(dp, -1); deque<int> Q; Q.push_front(T); dp[T] = 0;
while (!Q.empty()) {
int u = Q.front(); Q.pop_front();
if (u == S) return ;
if (vis[u]) continue ; vis[u] = true;
for (int v : G[u]) if (!-- deg[v]) {
if (!~dp[v] || dp[u] < dp[v]) dp[v] = dp[u], Q.push_front(v);
} else if (!~dp[v]) dp[v] = dp[u] + 1, Q.push_back(v);
}
} int main () { File(); n = read(); m = read();
For (i, 1, m) {
int u = read(), v = read();
G[v].push_back(u); ++ deg[u];
} S = read(), T = read(); Bfs(); printf ("%d\n", dp[S]); return 0;
}

Codeforces 346D Robot Control(01BFS)的更多相关文章

  1. Codeforces 346D Robot Control DP spfa 01BFS

    题意及思路:https://www.cnblogs.com/zjp-shadow/p/9562888.html 这题由于性质特殊,可以用01BFS来进行DP的转移. 代码: #include < ...

  2. Codeforces346D. Robot Control

    D. Robot Control time limit per test 6 seconds memory limit per test 256 megabytes input standard in ...

  3. LTE Module User Documentation(翻译14)——Uplink Power Control(上行功率控制)

    LTE用户文档 (如有不当的地方,欢迎指正!) 20 Uplink Power Control(上行功率控制)   上行功率控制功能默认是开启的.用户可以通过设置布尔属性 ns3::LteUePhy: ...

  4. [Notes] Reading Notes on [Adaptive Robot Control – mxautomation J. Braumann 2015]

    Reading sources: 1.Johannes Braumann, Sigrid Brell-Cokcan, Adaptive Robot Control (ARC  ) Note: buil ...

  5. 与众不同 windows phone (2) - Control(控件)

    原文:与众不同 windows phone (2) - Control(控件) [索引页][源码下载] 与众不同 windows phone (2) - Control(控件) 作者:webabcd介 ...

  6. Codeforces 828B Black Square(简单题)

    Codeforces 828B Black Square(简单题) Description Polycarp has a checkered sheet of paper of size n × m. ...

  7. HDU 4289 Control (网络流,最大流)

    HDU 4289 Control (网络流,最大流) Description You, the head of Department of Security, recently received a ...

  8. Codeforces I. Producing Snow(优先队列)

    题目描述: C. Producing Snow time limit per test 1 second memory limit per test 256 megabytes input stand ...

  9. Codeforces C. Maximum Value(枚举二分)

    题目描述: Maximum Value time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. Python之列表

    一.列表的特点 列表也是一种数据类型 列表元素是有序的,有编号的 列表元素的下标从0开始 列表中的每一个值叫一个元素,编号叫下标(索引/角标): stu_name=['崔海龙','杨帆','lrx', ...

  2. promise-笔记

    promise 封装Promise var fs = require('fs') function pReadFile(filePath) { return new Promise(function ...

  3. 简要了解 MySql 5.5/5.6/5.7/8 出现的新特性

    MySQL的开发周期 在比较之前,首先提一下MySQL的开发周期. MySQL一个大版本的开发,大致经历如下几个阶段: Feature Development Feature Testing Perf ...

  4. jmeter高并发设计方案(转)

    高并发设计方案二(秒杀架构) 优化方向: (1)将请求尽量拦截在系统上游(不要让锁冲突落到数据库上去).传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超 ...

  5. jmeter压测参数设定(转)

    jmeter压测参数设定 一.基本公式 线程数 = QPS * time: 注:QPS--每秒完成请求的个数:time--每个请求响应完成平均需要时间: 故QPS * time就是所有请求完成响应所需 ...

  6. flex实现三栏等分布局

    前言 在实际开发中,我们经常会想要实现的一种布局方式就是三栏等分布局,那么我们如何来解决这个问题呢? 解决 方法一:flex 外层容器也就是ul设置display:flex,对项目也就是li设置fle ...

  7. array_filter与array_map

    php数组array_filter函数和array_slice函数:<?php /* array_filter()用回调函数过滤数组中的单元 array_filter(array,functio ...

  8. (一)类数组对象NodeList

    NodeList对象的特点: NodeList是一种类数组对象,用于保存一组有序的节点. 可以通过方括号语法来访问NodeList的值,有item方法与length属性. 它并不是Array的实例,没 ...

  9. vue中的适配:px2rem

    这应该是vue项目在适配移动端时候,最简单的方法之一下面是基本步骤(使用cnpm)1.下载并引入lib-flexible cnpm install --save lib-flexible 在main. ...

  10. 莫烦scikit-learn学习自修第二天【算法地图】

    1. 算法地图