题意

有一个 \(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. K 班1-7,alpha,beta 作业成绩汇总

    K 班1-7,alpha,beta 作业成绩汇总 千帆竞发 详细得分 短学号 名 1 2 3 4 5 6 7 alpha beta TOTAL 505 基智 4.55 1 -2 0 0 -10 4.3 ...

  2. Python迭代器与格式化

    三元运算 对if-else判断的简写 >>> age = 18 >>> res = "You are so young!" if age < ...

  3. Masonry练习详解

    添加约束的方式: 1.通过使用NSLayoutConstraints添加约束到约束数组中,之前必须设置translatesAutoresizingMaskIntoConstraints = NO,即取 ...

  4. vue入门(一)

    通过JS引用vue就不说了,重点说一下使用npm搭建vue脚手架. (以下是windows系统下的操作,win7+) npm是个命令行工具,在搭建vue脚手架之前首先要安装nodeJS,下面是node ...

  5. 《梦断代码》Scott Rosenberg著(一)

    两打程序员,3年时间,4732个bug,只为打造超卓软件.  --序 在我们平时看到的大部分书籍只是讲技术和理论,但我们其实并不知道在真实的软件开发过程中,这些技术和理论究竟是被什么样的人如何去使用, ...

  6. vmware can not be closed virtual machine is busy

    VMware does not close when Windows Server 2003 ... |VMware Communities https://communities.vmware.co ...

  7. [新三板摘牌]国资企业济南华光光电去年终止拟IPO今年摘牌新三板

    国资企业济南华光光电去年终止拟IPO今年摘牌新三板 http://blog.sina.com.cn/s/blog_e32cfa770102ycku.html http://stock.qlmoney. ...

  8. VSCode 汉化

    https://jingyan.baidu.com/article/7e44095377c9d12fc1e2ef5b.html

  9. python语法糖/装饰器

    1.python高阶函数和嵌套函数 1.1高阶函数 def func1(x): return x**2 def func2(x): return x**3 def func(x,y): return ...

  10. Python图形用户界面

    1.使用Tkinter创建图形用户界面的步骤 (1)导入Tkinter模块,使用import Tkinter或from Tkinter import * (2)创建顶层窗口对象容器,使用top = T ...