一道特别好的深搜题+bfs

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道特别好的深搜题+bfs相关的知识,希望对你有一定的参考价值。

P2921 [USACO08DEC]Trick or Treat on the Farm G

深搜的技巧全用到了,写这个题解的人深搜也太好了吧
https://www.luogu.com.cn/problem/P2921

(改天加注释复习)

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
int nxt[maxn],n,cnt,f[maxn],h[maxn],fg;
bool vis[maxn];

int dfs(int u,int k)

    if(h[u])
        return h[u]-1+k;
    if(vis[u])
    
        h[u]=k-f[u];
        fg=u;
        return k-1;
    
    vis[u]=1;
    f[u]=k;
    int ans=dfs(nxt[u],k+1);
    if(fg)
    
        if(u==fg)
            fg=0;
        else
            h[u]=h[fg];
    
    else
        h[u]=h[nxt[u]]+1;
    vis[u]=0;
    return ans;


int main()

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    
        scanf("%d",&nxt[i]);
    
    for(int i=1;i<=n;i++)
    
        cout<<dfs(i,1)<<endl;
    
    return 0;

(2)
P3818 小A和uim之大逃离 II
bfs
step[x][y]表示到x行y列需要多少步,由于药剂的存在,需要加一维step[maxn][maxn][2],表示喝和没喝

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e3+5;
const int inf=0x3f3f3f3f;
int h,w,d,r,ans,step[maxn][maxn][2];
char mp[maxn][maxn];
bool vis[maxn][maxn];
int dx[4]=0,1,0,-1;
int dy[4]=1,0,-1,0;
struct node

    int x,y,d;
;
queue<node>q;
int main()

    scanf("%d%d%d%d",&h,&w,&d,&r);
    for(int i=1;i<=h;i++)
        for(int j=1;j<=w;j++)
        cin>>mp[i][j];
    memset(step,-1,sizeof(step));
    step[1][1][0]=0;
    q.push(1,1,0);
    while(!q.empty())
    
        node cur=q.front();q.pop();
        for(int i=0;i<4;i++)
        
            int x=cur.x+dx[i],y=cur.y+dy[i],g=cur.d;
            if(x<=0||x>h||y<=0||y>w||mp[x][y]=='#'||step[x][y][g]!=-1)
                continue;
            q.push(x,y,g);
            step[x][y][g]=step[cur.x][cur.y][cur.d]+1;
            if(g==0&&(x+d)>=1&&(x+d)<=h&&(y+r)>=1&&(y+r)<=w
               &&mp[x+d][y+r]=='.'&&step[x+d][y+r][1]==-1)
            
                q.push(x+d,y+r,1);
                step[x+d][y+r][1]=step[x][y][0]+1;
            
        
    
    if(step[h][w][0]==-1&&step[h][w][1]==-1)
        cout<<-1<<endl;
    else
    
        if(step[h][w][0]==-1)
            cout<<step[h][w][1]<<endl;
        else
            cout<<min(step[h][w][0],step[h][w][1])<<endl;
    
    return 0;

(3)
P1189 SEARCH

一个个方向的遍历。

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e3+5;
const int inf=0x3f3f3f3f;
int r,c,n,mp[maxn][maxn],ans[maxn][maxn];
char s[maxn][maxn];
bool vis[maxn][maxn];
int dx[4]=-1,1,0,0;
int dy[4]=0,0,-1,1;

void bfs(int dd)

    memset(vis,0,sizeof(vis));
    for(int i=1;i<=r;i++)
    
        for(int j=1;j<=c;j++)
        
            if(ans[i][j]&&!vis[i][j])
            
                vis[i][j]=1;
                ans[i][j]=0;
                int nx=i+dx[dd],ny=j+dy[dd];
                while(mp[nx][ny])
                
                    ans[nx][ny]=1;
                    vis[nx][ny]=1;
                    nx+=dx[dd];
                    ny+=dy[dd];
                
            
        
    

int main()

    scanf("%d%d",&r,&c);
    for(int i=1;i<=r;i++)
    
        for(int j=1;j<=c;j++)
        
            cin>>s[i][j];
            if(s[i][j]=='*')
            
                mp[i][j]=1;
                ans[i][j]=1;
            
            else if(s[i][j]=='.')
                mp[i][j]=1;
            else
                mp[i][j]=0;
        
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    
        string ss;cin>>ss;
        if(ss[0]=='N') bfs(0); //上
        if(ss[0]=='S') bfs(1);
        if(ss[0]=='W') bfs(2);
        if(ss[0]=='E') bfs(3);
    
    for(int i=1;i<=r;i++)
    
        for(int j=1;j<=c;j++)
        
            if(ans[i][j])
                cout<<'*';
            else if(s[i][j]=='*')
                cout<<'.';
            else
                cout<<s[i][j];
        
        cout<<endl;
    
    return 0;


以上是关于一道特别好的深搜题+bfs的主要内容,如果未能解决你的问题,请参考以下文章

CH2201小猫爬山

树的深搜和广搜

新学的深搜

NYOJ 353 3D dungeon bfs

7.1 深搜-子集和问题 (枚举子集+剪枝)

7.5 深搜-最佳调度问题(枚举排列+回溯+剪枝)