AcWing175電路維修

這是一道在luogu的藍題,在yxc大佬的講解下AC掉了(百般調試)node

首先這道題給了一個字符串矩陣,/ \表示相連哪兩個節點,只能夠走/ \所鏈接的兩個點,但咱們能夠旋轉每個邊,詢問從1,1 走到 n+1,m+1的最小旋轉次數。若是到不了就輸出no。c++

首先咱們要明確點的座標和對於點四周的格子上邊的座標。其次咱們考慮算法,發現這個邊權一個是0,一個是1,而且要搜最小步數,咱們考慮狄傑斯特拉發現是可行的,因此這也證實了bfs是正確的,而後對於這種問題咱們採用stl_deque來寫。對於deque,咱們對於每個點進行dijksra式的擴展,假如這個點做爲過front,那麼打標記,但入隊後不須要打標記,和普通的隊列不同,由於這裏存在屢次進隊的可能。而後運用四個方向數組以及一個正確匹配的邊進行判斷權值是1仍是0,鬆弛dist[tx][ty],假如鬆弛成功,咱們將其入隊,邊權爲0放到front,邊權爲1放到back。最後就是特判,假如終點的橫縱座標爲奇數,確定到不了。算法

1.對於格子圖和塊圖要分清楚,方向數組寫好,最後答案,越界判斷細心寫數組

2.多組數據,千萬別return 0了,特判的放在輸入後面,還有memsetspa

3.deque: 權0前1後,打當過head的點標記調試

代碼code

#include<bits/stdc++.h>
#define maxn 505
using namespace std;
char mp[maxn][maxn];
bool st[maxn][maxn];
int dist[maxn][maxn];
int n,m;
int xx[maxn],yy[maxn];
int T;
/*int dx[4]={-1,1,-1,1};
int dy[4]={-1,-1,1,1};
int ix[4]={-1,-1,0,0};
int iy[4]={-1,0,-1,0}; 
char cs[]="\\//\\";*/
char cs[] = "\\/\\/";
int dx[4] = {-1, -1, 1, 1}, dy[4] = {-1, 1, 1, -1};
int ix[4] = {-1, -1, 0, 0}, iy[4] = {-1, 0, 0, -1};
struct node{
    int x,y;
};
int bfs(){
    memset(dist,0x3f,sizeof(dist));
    memset(st,false,sizeof(st));
    dist[1][1]=0;    
    deque<node>q;
    q.push_back({1,1});
    while(q.size()){
        node a=q.front();
        q.pop_front();        
        if(st[a.x][a.y]==true) continue;//只能夠被當作一次堆頂 
        st[a.x][a.y]=true;
        for(int i=0;i<=3;i++){
            int tx=a.x+dx[i];
            int ty=a.y+dy[i];
            if(tx<1||ty<1||tx>n+1||ty>m+1) continue;
            int gx=a.x+ix[i];
            int gy=a.y+iy[i];
            int w=0;
            if(mp[gx][gy]!=cs[i]){
                w=1;
            }
            int d=w+dist[a.x][a.y];
            if(d<dist[tx][ty]){
                dist[tx][ty]=d;                
                if(w==1) q.push_back({tx,ty});//權爲1,後插 
                else q.push_front({tx,ty});//權爲0,前插 
            }
        }
    }    
    return dist[n+1][m+1];
}
int main(){
    cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin>>mp[i][j];
            }
        }
        if((n+m)%2!=0){
            cout<<"NO SOLUTION"<<endl;
            continue;
        }        
    cout<<bfs()<<endl;            
    } 
    return 0;
}
相關文章
相關標籤/搜索