解题思路:
要求两个点之间的最点距离,同时属于同一个洞窟的点他们之间的距离为0
那么该问题可以转换为求解两个洞窟的最短距离
依次构建的图是关于洞窟的而不是点
例如1 3 2 1 2 3:1和4点都属于1号洞窟那么他们两点邻接的其他点,也就等价于1号洞窟邻接了其他洞窟
从而构建洞窟的邻接表
然后通过bfs去求解两个洞窟之间的最小深度
bfs深度依次递增的,因此只要达到了终点洞窟此时的深度就是最小的深度
没必要再继续深度遍历
参考代码:
#include <bits/stdc++.h> using namespace std; int n,m; vector<int> a;//a[i]表示i所属于的洞窟编号 vector<int> b[5005];//存储洞窟之间的图 //通过bfs得到两个洞窟之间最近的距离 int solve(int x,int y){ if(x == y) return 0; queue<int> q; q.push(x); vector<int> depth(5005,0);//记录该洞窟编号到x的深度,即距离 vector<int> vis(5005,0);//标记访问避免重复访问 vis[x] = 1; //bfs遍历 while(!q.empty()){ int t = q.front(); q.pop(); for(int u : b[t]){ if(u == y) { //达到目的点,直接返回,通过bfs遍历 深度是从小到大 //因此第一次到达目的点就一定是最小的深度 return depth[t] + 1; } else { //已经入队了就跳过 if(vis[u]) continue; //入队 q.push(u); //标记入队 vis[u] = 1; //该点到x的深度是x到t的深度 + t到x深度(t是x的邻接点,故深度为1) depth[u] = depth[t] + 1; } } } } int main() { cin>>n>>m; a.resize(n + 1,0); for(int i = 1;i <= n;i++){ cin>>a[i]; } for(int i = 0;i < n-1;i++){ int x,y; cin>>x>>y; //构造的是洞窟图,例如1,3是1号洞窟,2,4,5是2号洞窟 //那么就构造1号洞窟和2号洞窟的关系 //1,3是1号洞窟,他们能到达的洞窟 合并起来就是1号洞窟能到达其他洞窟的情况 //这里还可以先进行去重处理,避免洞窟的邻接点有重复 if(a[x] != a[y]){//同一个洞窟的没必要再加入图结构 b[a[x]].push_back(a[y]); b[a[y]].push_back(a[x]); } } for(int i =0;i<m;i++){ int x,y; cin>>x>>y; //输出所求 其实就是这两点所属洞窟的最小深度(距离) cout<<solve(a[x],a[y])<<endl; } return 0; }
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复