带权值的图 BFS

时间:2024-07-19 19:07:08

用bfs遍历最图求最短路径时通常借用优先队列即优先考虑最大的或者最小的权值

方法1 优先队列:(内置函数,优先考虑较小的权值)

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
struct node{
int x,y,c;
bool friend operator < (node a,node b){
return a.c > b.c;//小的优先出来哦(没错就是大于号)
}
}r,w;
int n;
int dis[+][+];
int vis[+][+];
int ma[+][+];
int d[][]={,,,,-,,,-};
void bfs(int xx,int yy){ //bfs求终点到其余各点的最短路
priority_queue<node> q;
r.x = r.y = xx;
r.c = ma[n-][n-]; //以终点作为起点
dis[n-][n-] = ma[n-][n-];
vis[n-][n-] = ;
q.push(r);
while(!q.empty()){
r = q.top();
q.pop();
for(int i = ; i < ; i++){
int nx = r.x + d[i][];
int ny = r.y + d[i][];
if(nx < || ny < || nx >= n || ny >= n || vis[nx][ny]) continue;
w.x = nx;
w.y = ny;
w.c = r.c + ma[nx][ny];//把点(nx,ny)处的权值加上
vis[nx][ny] = ;//标记
q.push(w);
dis[nx][ny]=w.c;//跟新数组,保证每次都是最优的
}
} }
int main(){
cin>>n;
for(int i=;i< n;i++){
for(int j=;j< n;j++){
cin>>ma[i][j];
}
}
bfs(n-,n-);//这样一来数组里保存的就是其他点到点(n-1,n-1)的距离了;
for(int i=;i<n;i++)
{
cout<<endl;
for(int j=;j<n;j++)
printf("%d ",dis[i][j]);
}
return ; }

方法2:队列加判断条件(开一个数组step,加一个判断条件step [ d x ] [ d y ] > step [x] [y] + mp [dx] [dy] )

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define INF 100000000
using namespace std;
typedef long long ll;
struct stu{
int a,b;
};
int n;
ll arr[][];
ll step[][];
ll dp[][];
int d[][]={,,,,,-,-,};
void bfs(int x,int y){
queue<stu>que;
que.push({x,y});
step[x][y]=arr[x][y];
while(que.size()){
int xx=que.front().a;
int yy=que.front().b;
que.pop();
for(int i=;i<;i++){
int dx=xx+d[i][];
int dy=yy+d[i][];
if(dx>=&&dy>=&&dx<=n&&dy<=n){
if(step[dx][dy]>step[xx][yy]+arr[dx][dy]){
step[dx][dy]=step[xx][yy]+arr[dx][dy];//更新step数组,使他保存较小的的距离
que.push({dx,dy});
}
}
}
}
} int main(){
while(cin>>n)
{
for(int i=;i<=;i++){
for(int j=;j<=;j++)
step[i][j]=INF;
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
cin>>arr[i][j];
}
}
bfs(n,n);
for(int i=;i<=n;i++){
cout<<endl;
for(int j=;j<=n;j++)
cout<<step[i][j];//数组里的每一个点都是到(n,n)的最短距离
}
}
return ;
}
数据:
3
1 2 3
1 2 3
1 2 3