hdu 1728(bfs)

这题主要是解决一个多次访问取最优(转向次数最少)的问题,用vis数组记录每次访问的转向次数,当出现跟优解时此点再次入队。

#include<cstdio>
#include<queue>
#include<iostream>
using namespace std ;
int m, n, lim, si, sj, ei, ej ;
int tur[5][2] = {00010, -1, -1010, } ;
char map[101][101] ;
int vis[101][101] ;
struct node{
    int x, y, count ;
    int curtur ;
};
void bfs(){
    node begin ;
    begin.x = sj ;
    begin.y = si ;
    begin.count = 0 ;
    begin.curtur = -1 ;
    vis[sj][si] = 0 ;
    queue<node> q ;
    q.push(begin) ;
    while(!q.empty()){
        node p = q.front() ;
        q.pop() ;
        for(int k=1; k<=4; k++){
            node temp = p ;
            int i = temp.x + tur[k][0] ;
            int j = temp.y + tur[k][1] ;
            if(i>0&&i<=m&&j>0&&j<=n&&map[i][j]=='.'){
                if(p.curtur!=k&&p.curtur!=-1)
                    temp.count = p.count + 1 ;
                else
                    temp.count = p.count ;
                if(temp.count>lim)  continue ;
                if(i==ej&&j==ei){
                    printf("yes\n") ;
                    return ;
                }
                if(vis[i][j]>=temp.count){
                    temp.x = i ;
                    temp.y = j ;
                    temp.curtur = k ;
                    vis[i][j] = temp.count ;
                    q.push(temp) ;
                }
                //cout << temp.x << " " << temp.y << "  " << temp.count << endl ;
            }
        }
    }
    printf("no\n") ;
    return ;
}
int main(){
    int t ;
    scanf("%d", &t) ;
    while(t--){
        scanf("%d%d", &m, &n) ;
        for(int i=1; i<=m; i++)
            for(int j=1; j<=n; j++){
                cin >> map[i][j] ;
                vis[i][j] = 50 ;
            }
        scanf("%d%d%d%d%d", &lim, &si, &sj, &ei, &ej) ;
        if(map[ej][ei]=='*'){
            printf("no\n") ;
            continue ;
        }
        bfs() ;
    }
    return 0;

} 

原文地址:https://www.cnblogs.com/xiaolongchase/p/2268290.html