当前位置: 首页 > news >正文

多源BFS

多源

  • 超级源点和汇点
    • 最短距离[超级汇点]
    • 昂贵的聘礼
  • 多源BFS
    • 矩阵距离

超级源点和汇点

超级源点跟超级汇点是模拟出来的虚拟点,多用于图中:
<1>同时有多个汇点和一个源点,建立超级汇点
1、2、3、6分别到达4或者5或者7的最短路径,设立0这个超级汇点。
在这里插入图片描述
<2>同时有多个源点和一个汇点,建立超级源点
<3>同时有多个源点和多个汇点,建立超级源点和超级汇点

最短距离[超级汇点]

题目连接:https://www.acwing.com/problem/content/1490/
思路分析:这个题的关键就在于模拟出来一个超级汇点,对于每个村庄来说,目的地都是一个商店,具体是哪一个商店是不要求的,只需要找到最近的一个商店,也就是找到到这些商店集合的最短路径,虚拟出来一个超级汇点,到这些商店的路径都为0,这样每个村庄到达集合的最短路径其实就是到达这个超级汇点的最短路径了,也就相当于是这个超级汇点到每个点的最短路径,进行一次dijstra就行,也就简化成了求点到点的最短路径。
AC代码:

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N=100005;
const int INF=0x3f3f3f3f;
typedef pair<int,int>PII;
vector<PII>adj[N];
int dist[N];
bool visited[N];
int n,m,k,q,x;
priority_queue<PII,vector<PII>,greater<PII>>que;void dijistra(int s)
{for(int i=0;i<=n;i++)  dist[i]=INF; dist[s]=0; que.push({0,s});while(!que.empty()){int min=que.top().second;que.pop();if(visited[min]) continue;visited[min]=true;for(int i=0;i<adj[min].size();i++){if(!visited[adj[min][i].first]&&dist[min]+adj[min][i].second<dist[adj[min][i].first]){dist[adj[min][i].first]=dist[min]+adj[min][i].second;que.push({dist[adj[min][i].first],adj[min][i].first});}}}
}
int main()
{cin>>n>>m;while(m--){int u,v,c; cin>>u>>v>>c;  adj[u].push_back({v,c}); adj[v].push_back({u,c});}cin>>k;while(k--){cin>>x;   adj[0].push_back({x,0}); adj[x].push_back({0,0});}dijistra(0); cin>>q; while(q--){cin>>x; cout<<dist[x]<<endl;}return 0;
}

昂贵的聘礼

刷题链接:https://www.acwing.com/problem/content/905/
思路分析:到底怎么建立图是很关键的,必要的时候要加一些超级源点和超级汇点
还是注意要建立一个超级源点,表示最后终止继续交换下去的那个人的花费是他的物品的价格;
最后要保证求出来的最短路包含的结点的等级相互之间都不超过m,只能是枚举这个等级区间了,不能说每次更新邻接结点的时候判断该结点距离当前纳入最短路径集合的结点的距离,如果超过了m就不更新,这样只能保证相邻的两个结点的等级是不超过m的,但是最后最短路径包含的全部结点相互间不一定都不超过m,规则是只要跟一个很高的人交换了,后面涉及的所有等级很低的人都不能再进行交换
AC代码:

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N=105;
const int INF=0x3f3f3f3f;
typedef pair<int,int>PII;  //first表示未结点编号,second表示到达该结点的优惠 
vector<PII>adj[N];
int dist[N];
bool visited[N];
int m,n,p,l,x,t,v;
int Rank[N];   //存储每个结点的等级 
priority_queue<PII,vector<PII>,greater<PII>>que;int dijistra(int down,int up)  //传入区间等级最大和最小值 
{for(int i=0;i<=n;i++){dist[i]=INF; visited[i]=false;}dist[0]=0;que.push({0,0});while(!que.empty()){int min=que.top().second;que.pop();if(visited[min]) continue;visited[min]=true;for(int i=0;i<adj[min].size();i++){//超级源点跟谁都能到达 if(Rank[adj[min][i].first]>up||Rank[adj[min][i].first]<down) continue;   //等级相差太大,无法到达 if(!visited[adj[min][i].first]&&dist[min]+adj[min][i].second<dist[adj[min][i].first]){dist[adj[min][i].first]=dist[min]+adj[min][i].second;que.push({dist[adj[min][i].first],adj[min][i].first});}}}return dist[1];
}
int main()
{cin>>m>>n;for(int i=1;i<=n;i++){cin>>p>>l>>x;adj[0].push_back({i,p});   //建立超级源点到该点的边权Rank[i]=l;while(x--)  //替代品们 {cin>>t>>v;adj[t].push_back({i,v});   //建立替代品到该点的边权} }int ans=INF;for(int i=Rank[1]-m;i<=Rank[1];i++){ans=min(ans,dijistra(i,i+m));   //超级源点到每个点的最短路径 }cout<<ans<<endl; return 0;
}

多源BFS

单源BFS:起始阶段只需要将某一个元素加入队列
二叉树层序遍历
多源BFS:开始阶段加入多个元素入队列,可以将其理解为存在一个超级源点,然后进行宽搜扩展,第一阶段会把距离为0的点扩展进队列进行求解最短距离,第二阶段会把距离为1的点扩展进队列进行求解最短距离,第三阶段会把距离为2的点扩展进队列进行求解最短距离,…最后成功将所有点距离目标点的最短距离求出来了。

矩阵距离

题目链接:https://www.acwing.com/problem/content/description/175/
思路分析:曼哈顿距离实际就是从1位置处向外扩展,每次扩展距离加1
AC代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n,m;
typedef pair<int,int>PII;
queue<PII>tou;
const int INF=0x3f3f3f3f;
const int N=1005;
int grid[N][N];
int off[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
int main()
{cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){char t;cin>>t;if(t=='1') {grid[i][j]=0;tou.push({i,j});}else grid[i][j]=-1;}}while(!tou.empty()){int x=tou.front().first;int y=tou.front().second;tou.pop();for(int i=0;i<4;i++){int xi=x+off[i][0],yi=y+off[i][1];if(xi>=0 && yi>=0 &&xi<n && yi<m && grid[xi][yi]<0){tou.push({xi,yi});grid[xi][yi]=grid[x][y]+1;}}}for(int i=0;i<n;i++){for(int j=0;j<m;j++){cout<<grid[i][j]<<" ";}cout<<endl;}return 0;
} 
http://www.lryc.cn/news/118226.html

相关文章:

  • 自制电子农历
  • 解决nvm安装后,node生效但npm无效
  • Chrome DevTools 与 WebSocket 数据查看失焦的问题
  • Javascript 正则
  • C语言可变数组 嵌套的可变数组,翻过了山跨过了河 又掉进了坑
  • FFmpeg安装和使用
  • HTTP代理编程:Python实用技巧与代码实例
  • java调用第三方接口工具类 (HttpClientUtils.java)
  • f1tenth仿真设置
  • Technical debt (技术负债 / 技术债)
  • 【MATLAB第67期】# 源码分享 | 基于MATLAB的morris全局敏感性分析
  • ruby send call 的简单使用
  • 24聊城大学823软件工程考研
  • 勘探开发人工智能技术:机器学习(3)
  • 定制 ChatGPT 以满足您的需求 自定义说明
  • taro h5列表拖拽排序 --- sortablejs 和 react-sortable-hoc
  • Linux的shell脚本常用命令
  • 使用自己的数据集预加载 Elasticsearch
  • 机器视觉赛道持续火热,深眸科技坚持工业AI视觉切入更多应用领域
  • MyBatis操作数据库常见用法总结2
  • 基于SpringBoot+LayUI的宿舍管理系统 001
  • C语言笔记7
  • Centos更换网卡名称为eth0
  • 【Express.js】软件测试
  • TCP三次握手、四次握手过程,以及原因分析
  • OceanBase X Flink 基于原生分布式数据库构建实时计算解决方案
  • 600V EasyPIM™ IGBT模块FB30R06W1E3、FB20R06W1E3B11、FB20R06W1E3降低了系统成本和损耗,可满足高能效要求。
  • form 表单恢复初始数据
  • MySQL—索引
  • Android图形-合成与显示-概论