HDU

题意:给一个图,求连通块的个数。(题中是一某点周围8个点均为连通区域)

思路: 这道题就是一道很基础的搜索染色(计数),我一开始用的bfs但是一直MLE,所以就使用消耗空间更少的dfs

完整代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 101;
int n,m;
char map[maxn][maxn];
int vis[maxn][maxn];
int mov[][2] = {{1,0},{0,1},{-1,0},{0,-1},{1,1},{-1,-1},{-1,1},{1,-1}};
struct node{
    int x,y;
};
void dfs(node s)
{
    if(map[s.x][s.y]=='#'||vis[s.x][s.y]!=0||s.x<1||s.y<1||s.x>n||s.y>m)//不满足条件就返回
        return;
    vis[s.x][s.y]=1;//染色
    for(int i=0; i<8; i++)//判断往哪走
    {    
        node t;
        t.x=s.x+mov[i][0];
        t.y=s.y+mov[i][1];
        if(map[t.x][t.y]=='@'&&vis[t.x][t.y]==0&&t.x>0&&t.x<=n&&t.y>0&&t.y<=m)
        {
            dfs(t);
        }
    }
}
//void bfs(node s){ //bfs中queue开的空间太大 
//    queue<node>Q;
//    Q.push(s);
//    while(Q.size()){
//        node t = Q.front();
//        vis[t.x][t.y]  =1;//访问 
//        Q.pop();
//        for(int i=0;i<8;i++){
//            node nex;
//            nex.x =t.x+ mov[i][0];
//            nex.y =t.y+ mov[i][1];
//            if(nex.x<1||nex.y<1||nex.x>n||nex.y>m) continue;//边界条件 
//            else if(vis[nex.x][nex.y]||(map[nex.x][nex.y]=='*')) continue;
//            else{
//                Q.push(nex);
//            }
//        }
//    }
//}

int getblocks(){
    int cnt = 0;
    for(int i =1;i<=n;i++)
        for(int j=1;j<=m;j++){
                if(!vis[i][j]&&(map[i][j]=='@')) {
                    cnt++;    
                    node s;
                    s.x = i,s.y = j;
                    dfs(s);
                }
                
            }
    return cnt;
}



int main(){
    while(cin>>n>>m){
        char ch;
        memset(vis,0,sizeof(vis));
        if(n==0&&m==0) break;
        for(int i =1;i<=n;i++)
            for(int j=1;j<=m;j++){
                cin>>ch; 
                map[i][j] = ch;
            }     
        int ans = getblocks();
        cout<<ans<<endl; 
    } 
} 
原文地址:https://www.cnblogs.com/Tianwell/p/11263021.html