【每日一题】7月7日题目精讲—最短路

来源:牛客网:

文章目录

    • 题目描述
    • 题解:
    • 代码:

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
64bit IO Format: %lld

题目描述

给一个连通图,每次询问两点间最短路。每条边的长度都是1。 输入描述: 第一行两个整数n和m,表示图的点数和边数(1≤ n≤ 100000,
1≤ m≤ n+100)。 接下来m行每行两个整数a和b,表示一条边(1≤ a, b≤ n)。保证没有自环和重边。保证图连通。
接下来一个整数q表示询问的个数(1≤ q≤ 100000)。 接下来q行每行两个整数a和b表示询问a和b之间的最短路。

输出描述:

每个询问输出一行表示答案。

示例1
输入

4 5
1 2
2 3
1 4
4 3
2 4
4
1 4
1 2
2 4
1 3

输出

1
1

题解:

我看了别人的讲解才逐渐明白。。我太菜了
题目是最短路,题目内容也是最短路,但是解法却不是常用的spfa等,因为询问的个数有点多(1 ~ 100000)
我们仔细看数据范围,m<n+100,什么意思?想想m = n-1时是一棵树,那我们就可以把他当做树处理,然后剩下的边再慢慢干
如果当做一棵树的话,边长为1,求最短路径,我们就可以通过最近公共祖先(lca)得到两点的最近距离,dep[a]+dep[b] - 2dep [ lca(a, b) ] (a的深度+b的深度,然后a和b有重复的部分,减去重复的部分)
然后我们看看多出来的100个边,会对结果有什么影响?
在这里插入图片描述
蓝色是原本的树,橙色,绿色是多出来的边
如果是橙色,对结果没有影响,如果是绿色会有影响
那么该如何处理?
我们可以把剩下多出来的边跑单元最短路(以这些边的一个端点开始)并记录下来
然后与原路径进行比较
a到b的最小距离就在dep[a] +dep[b]-2
dep[ lca(a,b) ]与dis[a[i]]+dis[b[i]]中取最小值
不知道有没有听明白,我拿样例做个分析:
我们看一下样例,

1 2
2 3
1 4
4 3
2 4

多余的边是:1-2 , 4-3,
在这里插入图片描述
ans最开始的值就是树上的lca
ans={1,2,1,3}
然后开始跑1-2这个边,从1这个点开始,计算出1到个点的距离
dis={0,1,2,1}
然后更新最短距离:
ans[i] = min(ans[i], dis[a[i]] + dis[b[i]]);
a和b分别表示询问中a和b的距离
a[2]=1,b[2]=2
dis[a[2]]+dis[b[2]]=0+1=1<ans[2]
所以ans[2]=1
大致就是这个过程

代码:

代码来自

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define endl '\n'
#define SZ(x) (int)x.size()
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int mod = 1e9+7;
//const int mod = 998244353;
const double eps = 1e-10;
const double pi = acos(-1.0);
const int maxn = 1e6+10;
const ll inf = 0x3f3f3f3f;
const int dir[][2]={{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
int n, m, depth[maxn], f[maxn][50];
int from[maxn], to[maxn << 1], nxt[maxn << 1], cnt = 1, Log[maxn], From[maxn];
bool vis[maxn], used[maxn];
//链式前向星加边
void addEdge (int u, int v) {From[++cnt] = u, to[cnt] = v, nxt[cnt] = from[u], from[u] = cnt;
}
//计算深度&计算祖先
void dfs (int u, int fa) {depth[u] = depth[fa] + 1;vis[u] = 1;for (register int i = 1; i <= Log[n]; ++i) {if ((1 << i) > depth[u]) break;f[u][i] =  f[f[u][i - 1]][i - 1];}for (register int i = from[u]; i; i = nxt[i]) {ll v = to[i];if (vis[v]) continue;used[i] = used[i ^ 1] = 1;f[v][0] = u;dfs (v, u);}
}
//计算LCA
inline int LCA (int x, int y) {if (depth[x] < depth[y]) swap(x, y);//我们默认x为更深的那个点for(register int i = Log[n] ; i >= 0 ; --i)if(depth[x] - (1 << i) >= depth[y]) x = f[x][i];//将x跳到和y同一深度上if (x == y) return x;for (register int i = Log[n]; i >= 0; --i)if (f[x][i] != f[y][i])x = f[x][i], y = f[y][i];//一起向上跳return f[x][0];//不难看出,此时两个点均在其LCA的下方,往上跳一次即可
}
void init(){Log[0] = -1;for (register int i = 1, u, v; i <= m; ++i) {cin >> u >> v;addEdge (u, v); addEdge(v, u);Log[i] = Log[i >> 1] + 1;}Log[n] = Log[n >> 1] + 1;dfs(1, 0);
}
int dist(int p , int q){return depth[p] + depth[q] - 2 * depth[LCA(p , q)];}
int ans[maxn],a[maxn],b[maxn],dis[maxn], Q, q[maxn], h, t;
void bfs(int s){for (int i = 1; i <= n; i++)dis[i] = inf;dis[s] = 0;h = t = 0;q[++h] = s;while (t < h) {int u = q[++t];for (int i = from[u]; i; i = nxt[i]){int v = to[i];if (dis[v] > dis[u] + 1)dis[v] = dis[u] + 1, q[++h] = v;}}for (int i = 1; i <= Q; i++)ans[i] = min(ans[i], dis[a[i]] + dis[b[i]]);
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//  freopen("in.txt", "r", stdin);
//  freopen("out.txt", "w", stdout);cin >> n >> m;init();cin >> Q;for (int i = 1; i <= Q; i++){cin >> a[i] >> b[i];ans[i] = dist(a[i], b[i]);}int num = 0;for (int i = 2; i <= cnt; i++)if(!used[i]) {used[i] = used[i ^ 1] = 1;bfs(From[i]);num++;if(num > 101) break;}for (int i = 1; i <= Q; i++)cout << ans[i] << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【活动(广州)】office365的开发者训练营

Office 365每月有超过1亿的商业活跃用户&#xff0c;是现有最大的生产力服务。Office 365为开发人员提供了一个令人难以置信的机会&#xff0c;包括业务关键数据和数百万用户&#xff0c;以及一个旨在让人们保持工作流程的平台。作为一名开发人员&#xff0c;您可以使用每天使用…

牛客网【每日一题】7月8日 Alliances

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 5秒&#xff0c;其他语言10秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 树国是一个有n个城市的国家&#xff0c;城市编号…

Ocelot简易教程(四)之请求聚合以及服务发现

上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍&#xff0c;今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能。希望能对大家有所帮助。作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9695639.html请求聚合Ocelot允…

邓公数据结构C++语言版学习笔记1

1. 对于计算幂2n2^n2n的算法优化 暴力算法时间复杂度O(n)O(n)O(n) __int64 power2BF_I(int n) //幂函数2^n算法&#xff08;蛮力迭代版&#xff09;&#xff0c;n > 0{ __int64 pow 1; //O(1)&#xff1a;累积器刜始化为2^0while (0 < n --) //O(n)&#xff1a;迭代n轮…

HttpClientFactory系列二:集成Polly处理瞬态故障

前言&#xff1a;最近&#xff0c;同事在工作中遇到了使用HttpClient,有些请求超时的问题&#xff0c;辅导员让我下去调研一下&#xff0c;HttpClinet的使用方式已经改成了之前博客中提到的方式&#xff0c;问题的原因我已经找到了&#xff0c;就是因为使用了伪异步&#xff0c…

邓公数据结构C++语言版学习笔记——二叉树

二叉树的遍历 一. preorder——先序遍历VLR 1. 递归先序遍历 2. 迭代先序遍历 3.先序遍历图解 二. inorder——先序遍历LVR 1. 递归中序遍历 2.迭代中序遍历 3.迭代中序遍历优化空间复杂度 <1>定义直接后继 <2>借用直接后继优化算法 解释&#xff1a;…

二分图匹配--匈牙利算法

文章目录二分图&#xff1a;匹配匈牙利算法代码&#xff1a;二分图&#xff1a; 二分图是一个无向图&#xff0c;点集分成子集X和Y&#xff0c;图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时&#xff08;包括0&#xff09;&#xff0c;G就是一个…

《Office 365开发入门指南》上市说明和读者服务

写在最开始的话拙作《Office 365开发入门指南》上周开始已经正式在各大书店、在线商城上市&#xff0c;欢迎对Office 365的开发、生态感兴趣的开发者、项目经理、产品经理参考本书&#xff0c;全面了解Office 365带来的全新机遇以及在具体业务应用开发中的场景。写作本书差不多…

简单理解手机快充

浅谈手机快充 背景 智能手机发展这么些年&#xff0c;屏幕显示越来越清晰&#xff0c;拍照像素越来越高&#xff0c;处理器性能越来越强&#xff0c;运行内存甚至开始超过PC&#xff0c;不过手机的续航还是一个问题&#xff1a;处理器性能以及一系列的增强无疑对电池是一个巨…

【送书活动】C# 程序员的自我修养

如果希望成为一个C# 高手&#xff0c;或者至少是合格的C# 程序员&#xff0c;应该懂些什么&#xff1f;《C#从现象到本质》&#xff08;以下简称本书&#xff09;试图回答这个问题。实际上&#xff0c;在本书问世之前&#xff0c;市面上已经有很多优秀的C# 书籍&#xff0c;例如…

张善友:自由之精神,中国之队长

张善友&#xff0c;毕业于兰州大学数学系&#xff0c;2006年开始连任微软最有价值专家&#xff08;MVP&#xff09;&#xff0c;一直在社区宣导.NET开源项目&#xff0c;从早期的Mono到.NET Core&#xff0c;在社区被尊称为张队长&#xff0c;在腾讯工作11年后&#xff0c;进行…

CF461D-Appleman and Complicated Task【并查集】

正题 题目链接:https://www.luogu.com.cn/problem/CF461D 题目大意 n∗nn*nn∗n的网格需要填上xxx或ooo&#xff0c;其中有kkk个格子已经固定&#xff0c;求有多少中填写方案使得每个格子的四周都有偶数个ooo。 解题思路 约束条件相当于一个格子周围的异或和都为000&#xff…

工科数学分析无穷级数总结

目录序言一.常数项级数概念1. 什么是常数项无穷级数&#xff1f;2. 级数的收敛性与和两个特别的级数级数的判别方法①常数项级数判别法②正项级数的审敛准则③变号级数的审敛准则④绝对收敛二.函数项级数概念1. 什么是函数项级数&#xff1f;2. 函数项级数处处收敛与和函数一致…

dump解析入门-用VS解析dump文件进行排障

突然有一天部署在服务器的一个应用挂掉了&#xff0c;没办法只能进入服务器打开【事件查看器】查看下&#xff0c;好不容易找到了打开后一脸懵逼事件查看器查到的内容根本对我们排障没有任何作用。在这个时候如果有对应的dump文件就能派上用场了&#xff0c;只要有dump文件就能…

.NET Core部署中你不了解的框架依赖与独立部署

作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9703460.htmlNET Core项目发布的时候你有没有注意到这两个选项呢&#xff1f;有没有纠结过框架依赖与独立部署到底有什么区别呢&#xff1f;如果有的话那么这篇文章可以参考下&#xff01;为什么…

dump文件解析之探索.Net的内存

前言&#xff1a;对于需要长时间运行的.net程序&#xff0c;有时需要我们查看内存的使用有没有内存泄露问题。我们可以从dump文件中找到答案。Dump的看点用dump文件来分析内存&#xff0c;到底我们需要关心哪些点呢&#xff1f;内存的使用情况 HeapSize/object的数量 也就是托管…

微软发布Azure Pipelines,开源项目可无限制使用CI/CD

微软发布了Azure Pipelines&#xff0c;他们新的CI/CD服务&#xff0c;是Azure DevOps产品的一部分。Azure Pipelines可用于构建、测试和部署工作负载&#xff0c;并可以让各种语言、项目类型和平台协同工作。作为Visual Studio Team Services&#xff08;VSTS&#xff09;的后…

2020牛客暑期多校训练营(第一场)

文章目录A B-Suffix ArrayB Infinite TreeC DominoD Quadratic FormE Counting Spanning TreesF Infinite String Comparision题意&#xff1a;题解&#xff1a;代码&#xff1a;G BaXianGuoHai, GeXianShenTongH Minimum-cost FlowI 1 or 2J Easy Integration题意题解代码2020…

C# 接受MQTT服务器推送的消息

前言&#xff1a;MQTT是IBM开发的一个即时通讯协议。MQTT是面向M2M和物联网的连接协议&#xff0c;采用轻量级发布和订阅消息传输机制。大家可以直接上GitHub下载MQQT服务的源码&#xff0c;源码地址&#xff1a;https://github.com/mqtt/mqtt.github.io/wiki/libraries主要内容…

Boundary(2020多校第二场B)

Boundary&#xff08;2020多校第二场B&#xff09; 文章目录题意&#xff1a;题解&#xff1a;思路1&#xff1a;代码&#xff1a;思路二代码题意&#xff1a; 坐标平面有n个点&#xff08;不与原点&#xff08;0,0&#xff09;重复&#xff09;,现考虑一个圆&#xff0c;&…