双端队列_01bfs _ 最短路

概述

作用:
求图中只有两种权值边的最短路

理解:
如果我们的图中只有两种边0或者1(1也可以是任意的正数)。
每次从队头取出元素,我们就可以使用一个双端队列来模拟dij中的优先队列:

  • 如果扩展到的边权值为0,就放入队头。
  • 如果扩展到的边权值为1,就放入队尾。

很显然这样是满足优先队列的。因此算法是正确的。

模板代码

写法和dij的一样

vector<pii> g[N];
int dist[N];
bool vis[N];
void bfs(int be,int en){
    dist[be]=0;
    deque<int> q;
    q.push_back(be);
    while(q.size()){
        int k=q.front();
        q.pop_front();
        if(vis[k]) continue;
        vis[k]=true;
        for(pii t: g[k]){
            int ver=t.first,dis=t.second;
            int cnt=dist[k]+dis;
            if(dist[ver]>cnt){
                dist[ver]=cnt;
                if(dis) q.push_back(ver);
                else q.push_front(ver);
            }
        }
    }
    cout<<dist[en]<<endl;
}

应用

P4554 小明的游戏 模板题

175. 电路维修

代码:

#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
// #define int long long
const int N = 510,M=N*N;
int n,m;
char g[N][N];
int dist[N][N];
bool st[N][N];
int dx[]={-1,-1,1,1},dy[]={-1,1,1,-1};//相邻点
int ix[]={-1,-1,0,0},iy[]={-1,0,0,-1};//相邻边
int  bfs(){
    memset(dist,0x3f,sizeof dist);
    memset(st,0,sizeof st);
    //四个方向正确的方向 (\\就是\ 因为是转义字符所以写两个)
    char cs[]="\\/\\/";

    dist[0][0]=0;
    deque<pii> q;
    q.push_back({0,0});
    while(q.size()){
        pii k=q.front();
        q.pop_front();
        int x=k.first,y=k.second;
        if(st[x][y]) continue;
          st[x][y]=true;

        for(int i=0;i<4;i++){
            int a=x+dx[i],b=y+dy[i];
            if(a<0 || a>n || b<0 || b>m) continue;
            //更新路径,求长度
            int ca=x+ix[i],cb=y+iy[i];
            
            int d=dist[x][y]+(g[ca][cb]!=cs[i]);
            if(dist[a][b]>d){
                dist[a][b]=d;
                if(g[ca][cb]!=cs[i]) q.push_back({a,b});
                else q.push_front({a,b});
            }
        }
    }
    return dist[n][m];
}
void solve()
{
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>g[i];
   int t=bfs();
   if(t==0x3f3f3f3f) puts("NO SOLUTION");
   else cout<<t<<endl;
}
signed main()
{
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
    int t = 1;
    cin>>t;
    while (t--)
        solve();
    return 0;
}

posted @ 2022-08-08 20:59  kingwzun  阅读(271)  评论(0编辑  收藏  举报