题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=5049

题解

题面里面满眼的随机。既然数据完全随机,那就是在锻炼选手的乱搞能力啊。

根据一个常用的结论,一棵随机的树的深度不超过 \(\log n\),大概等价于一个点期望下有 \(2\) 个孩子。

那么这个图中,以某个点为根的最短路树也应该满足。不妨设 \(dis(u,v) = l\),根据之前的结论,\(l \leq \log n\)。那么如果直接暴力 bfs 建最短路的话,需要遍历 \(2^l = n\) 个点。这样的情况可以使用双向 bfs,这样需要遍历的点就只有 \(2\cdot 2^{\frac l2} = \sqrt n\) 个点。


代码如下,在期望情况下的时间复杂度为 \(O(k\sqrt n)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 100000 + 7;
const int M = 300000 + 7; int n, m, qq;
int fa[N], sz[N], q[N], vis[N], dis[N]; struct Edge { int to, ne; } g[M << 1]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); } inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline void merge(int x, int y) {
x = find(x), y = find(y);
if (sz[x] < sz[y]) std::swap(x, y);
fa[y] = x, smax(sz[x], sz[y] + 1);
} inline int bfs(int s, int t) {
int hd = 0, tl = 0;
q[++tl] = s, vis[s] = 1, dis[s] = 0;
q[++tl] = t, vis[t] = -1, dis[t] = 0;
while (hd < tl) {
int x = q[++hd];
for fec(i, x, y) if (!vis[y]) dis[y] = dis[x] + 1, vis[y] = vis[x], q[++tl] = y;
else if (vis[y] != vis[x]) {
for (int i = 1; i <= tl; ++i) vis[q[i]] = 0;
return dis[x] + dis[y] + 1;
}
}
return -1;
} inline void work() {
while (qq--) {
int x, y;
read(x), read(y);
if (find(x) != find(y)) puts("-1");
else printf("%d\n", bfs(x, y));
}
} inline void init() {
read(n), read(m), read(qq);
int x, y;
for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
for (int i = 1; i <= m; ++i) read(x), read(y), adde(x, y), merge(x, y);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj5049 [Lydsy1709月赛]导航系统 双向bfs的更多相关文章

  1. 【bzoj5049】[Lydsy九月月赛]导航系统 并查集+双向BFS最短路

    题目描述 给你一张 $n$ 个点 $m$ 条边的随机图,边权为1.$k$ 次询问两点间最短路,不连通则输出-1. 输入 第一行包含3个正整数n,m,k(2<=n<=100000,1< ...

  2. POJ1915Knight Moves(单向BFS + 双向BFS)

    题目链接 单向bfs就是水题 #include <iostream> #include <cstring> #include <cstdio> #include & ...

  3. HDU 3085 Nightmare II 双向bfs 难度:2

    http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...

  4. POJ 3170 Knights of Ni (暴力,双向BFS)

    题意:一个人要从2先走到4再走到3,计算最少路径. 析:其实这个题很水的,就是要注意,在没有到4之前是不能经过3的,一点要注意.其他的就比较简单了,就是一个双向BFS,先从2搜到4,再从3到搜到4, ...

  5. [转] 搜索之双向BFS

    转自:http://www.cppblog.com/Yuan/archive/2011/02/23/140553.aspx 如果目标也已知的话,用双向BFS能很大程度上提高速度. 单向时,是 b^le ...

  6. 双向BFS

    转自“Yuan” 如果目标也已知的话,用双向BFS能很大提高速度 单向时,是 b^len的扩展. 双向的话,2*b^(len/2)  快了很多,特别是分支因子b较大时 至于实现上,网上有些做法是用两个 ...

  7. HDU 3085 Nightmare Ⅱ (双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. HDU 3085 Nightmare Ⅱ 双向BFS

    题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...

  9. POJ 3126 Prime Path 解题报告(BFS & 双向BFS)

    题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...

随机推荐

  1. Redis使用场景一,查询出的数据保存到Redis中,下次查询的时候直接从Redis中拿到数据。不用和数据库进行交互。

    maven使用: <!--redis jar包--> <dependency> <groupId>redis.clients</groupId> < ...

  2. springboot整合 thymeleaf 案例

    1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springBo ...

  3. php substr()函数 语法

    php substr()函数 语法 作用:截取字符串 语法:substr(string,start,length)大理石平台 参数: 参数 描述 string 必需.规定要返回其中一部分的字符串. s ...

  4. MapGIS IGServer for java

    但是安装完之后,服务里面没有找到igserver服务 IGServer SManager cxf 怎么会找不到类呢?是服务映射出了问题,所以目录找不到.所以怎么配置目录呢?是在xml还是环境变量,还是 ...

  5. Jenkins 添加新用户

    下面重点记录下jenkins安装后的一些配置: (1)添加用户权限 jenkins初次登陆后,要先注册一个用户作为管理员: 依次点击“系统管理”->“Configure Global Secur ...

  6. 命令行下DEBIAN7时间错误的问题(转)

    Debian下的时间设置问题 Debian系统经常会遇到时间不准的情况,以下几个步骤可让您轻松摆脱烦恼: 1.设定正确的时区编辑/etc/timezone,写入Asia/Shanghai 2.使用da ...

  7. hihocoder 1015 : KMP算法(kmp)

    传送门 Description 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一只河蟹,于是河蟹就向小H ...

  8. git团队协作代码提交步骤

    我们公司由五个人同时开发一个项目,大佬建好仓库后叫我们统一提交到dev这个分支,我的分支是hardy,你们只要将这两个值改成你们团队协作中使用的分支即可.代码如下: git add . git com ...

  9. 配置NAT实验

    实验拓扑: 下面先配置静态NAT:(将私网地址转为公网地址)内部地址到外部地址的1对1转换 1.先配置出口静态路由,指向公网入口路由器 2.nat static命令配置1对1的IP地址转换 3.测试: ...

  10. JedisPool使用注意事项

    转自:http://www.cnblogs.com/wangxin37/p/6397783.html JedisPool使用注意事项: 1.每次从pool获取资源后,一定要try-finally释放, ...