1. 程式人生 > >P1141 01迷宮 題解

P1141 01迷宮 題解

這道題我一共寫了22遍,最後AC的時候手都在顫抖,,,

先說一下思路,洛谷有大佬用並查集,等等各種高階操作。雖然我也用並查集寫了,但是效果不是太理想。

我的思路是G[ ][ ]存放圖,V[ ][ ]並不是存放圖狀態,V[ ] [ ]存放這是第幾個連通圖,再用一個數組a[ ] 來存放每個聯通圖的元素數量,配合經典寬度搜索,得出答案。

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int n,m,G[1010][1010],x,y,maxv=0,f[1010][1010];//f就是大家經常用的v狀態陣列,只不過這裡存放聯通圖編號。 
int num=1,a[1000010],next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//num是每個連通圖獨有的編號,從1開始。a[]是存放每個圖的個數(a[num]).
void bfs(int x,int y){
    int x1,y1;
    for(int i=0;i<4;i++){
        x1=x+next[i][0];
        y1=y+next[i][1];
        if(1<=x1&&x1<=n&&1<=y1&&y1<=n&&!f[x1][y1]&&(G[x1][y1]!=G[x][y])){
            f[x1][y1]=num;
            maxv++;
            bfs(x1,y1);
        }
    }
}//經典廣度搜索,每次搜尋都會得出一個maxv元素個數
int main(){
    int x1,y1;
    cin>>n>>m;
    char c[1100];
    for(int i=1;i<=n;i++){
        scanf("%s",c);
        for(int j=1;j<=n;j++)
            if(c[j-1]=='1')G[i][j]=1;
    }//輸入圖
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            if(!f[i][j]){//如果這個點沒有在任何圖中
                num++;//編號加1
                maxv=1;//初始化最大元素數
                f[i][j]=num;
                bfs(i,j);
                a[num]=maxv;//存放圖的元素個數
            } 
        }    
      while(m--){
        cin>>x1>>y1;
        cout<<a[f[x1][y1]]<<endl;    //輸出
    }
}