特殊的bfs——01BFS

0-1BFS用来解决:边权值为0或1,或者能够转化为这种边权值的最短路问题,时间复杂度O( v点+e边 )。

主要操作:用deque,从0边扩展到的点push到队首,反之则到队尾。

 

模板题:SPOJ - KATHTHI

题意:起点走到终点,n×m的网格,每个位置有一个小写字母,若s[x][y]=s[nx][ny],则移动的花费为0,否则花费为1,求花费最少

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
#define ri register int
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e3+100;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
struct node
{
    int x,y;    
};
node s,t;
int n,m,k,T;
char G[maxn][maxn];
struct _01bfs
{
    deque<node> q;
    int dis[maxn][maxn];
    int x,y,xx,yy;
    bool vis[maxn][maxn];
    node now;
    bool flag;
    void init()
    {
        memset(dis,0x3f,sizeof(dis));
        //memset(vis,0,sizeof(vis));
        q.clear();
    }
    int bfs()
    {
        q.push_front(s);
        dis[s.x][s.y]=0;
        while (!q.empty())
        {
            now=q.front();
            q.pop_front();
            //if (vis[now.x][now.y]) continue;    一般情况下,可以不用 
            //vis[now.x][now.y]=1;
            for (int i=0;i<4;i++)
            {
                x=now.x,y=now.y;
                xx=x+dx[i],yy=y+dy[i];
                if (xx<0||xx>=n||yy<0||yy>=m) continue;
                flag=1;
                if (G[x][y]==G[xx][yy]) flag=0;
                if (dis[x][y]+flag<dis[xx][yy])  // 如果是<=就要用vis 
                {
                    dis[xx][yy]=dis[x][y]+flag;
                    if (!flag) q.push_front({xx,yy});
                        else q.push_back({xx,yy});
                }
            }
        }
        return dis[t.x][t.y];
    }
}hehehe;
int main()
{
    T=read();
    while (T--)
    {
        n=read(),m=read();
        for (int i=0;i<n;i++) scanf("%s",G[i]);
        s.x=0,s.y=0,t.x=n-1,t.y=m-1;
        hehehe.init();
        cout<<hehehe.bfs()<<endl;
    }
    return 0;
}
View Code

 

相似题:UVA11573  Ocean Currents

题意类似

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
#define ri register int
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e3+100;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
const int dx[8]={-1,-1,0,1,1,1,0,-1};
const int dy[8]={0,1,1,1,0,-1,-1,-1};
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
struct node
{
    int x,y;    
};
node s,t;
int n,m,k;
char G[maxn][maxn];
struct _01bfs
{
    deque<node> q;
    int dis[maxn][maxn];
    int x,y,xx,yy;
    bool vis[maxn][maxn];
    node now;
    bool flag;
    void init()
    {
        memset(dis,0x3f,sizeof(dis));
        //memset(vis,0,sizeof(vis));
        q.clear();
    }
    int bfs()
    {
        q.push_front(s);
        dis[s.x][s.y]=0;
        while (!q.empty())
        {
            now=q.front();
            q.pop_front();
            if (now.x==t.x && now.y==t.y) break;
            //if (vis[now.x][now.y]) continue;   一般情况下,可以不用 
            //vis[now.x][now.y]=1;
            for (int i=0;i<8;i++)
            {
                x=now.x,y=now.y;
                xx=x+dx[i],yy=y+dy[i];
                if (xx<1||xx>n||yy<1||yy>m) continue;
                flag=0;
                if (G[x][y]-'0'==i) flag=1;
                if (dis[x][y]+!flag<dis[xx][yy])  // 如果是<=就要用vis 
                {
                    dis[xx][yy]=dis[x][y]+!flag;
                    if (flag) q.push_front({xx,yy});
                        else q.push_back({xx,yy});
                }
            }
        }
        return dis[t.x][t.y];
    }
}hehehe;
int main()
{
    n=read(),m=read();
    for (int i=1;i<=n;i++) scanf("%s",G[i]+1);
    k=read();
    for (int i=1;i<=k;i++)
    {
        s.x=read(),s.y=read(),t.x=read(),t.y=read();
        hehehe.init();
        cout<<hehehe.bfs()<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-05-02 23:59  Y-KnightQin  阅读(1909)  评论(0编辑  收藏  举报