poj2386--图的遍历

poj2386--图的遍历
题意描述:
要求输出图中连通分支的个数。
最简单的图遍历问题,题目虽然简单,却考察了最基本的遍历知识。
图的常见遍历方式有两种:深度优先遍历和广度优先遍历,他们的作用是将图中的每个点都访问一遍,只不过是顺序不同。
如果把图中的每条边长都相等(比如都是1)的话,深度优先遍历的过程是:
1.任意选定一个点p0作为遍历的起点
2.从未访问节点中任选一个距离p0最近的点进行访问,并标记该点被访问过
3.重复第2步,直到该连通分支中的所有节点都被访问过
说的形象一点,深度优先遍历就是按照层次的顺序访问节点,每一层中的节点与p0有相同的距离。先访问第一层,再访问第二层,……
深度优先遍历过程就是尽可能深的去访问节点,具体过程为:
1.任意选定一个点p0作为遍历的起点
2.当访问到某一个节点p1时,如果p1下面有未被遍历的子节点,我们就接着访问p1的某一个未被遍历子节点,并标记该子节点被访问过,
3.如果p1不存在未被访问的子节点,我们就退回到p1的父节点,并执行第2步
4.执行第2、3步,直到所有节点被访问过。
(递归过程真心不好描述啊~~~)
大家也看出来了,深度优先遍历的是一个递归的过程,因此很容易想到要用到栈这种数据结构,具体实现的时候可以用递归,也可以用栈。看个人习惯了。
广度优先遍历实现就要用到队列了。
以下是poj2386不同实现方式的代码
深度优先遍历,递归实现:

#include<stdio.h>
#include
<stdlib.h>
#include
<string.h> //stack, Recursion
#define LEN 110
char mp[LEN][LEN];
int N, M;
int d[8][2= {-1-1-10-110-1011-11011};
//d[][]是各个方向上的增量
void DFS(int x0, int y0)
{
    
int i, j;
    mp[x0][y0] 
= 'X';//标记该节点被访问过
    for(i = 0; i < 8; i++)
    {
        
int x1 = x0 + d[i][0];
        
int y1 = y0 + d[i][1];
        
if(mp[x1][y1] == 'W')
            DFS(x1, y1);
    }
}
int main() 
{
    
int i, j;
    
while(scanf("%d%d"&N, &M) != EOF)
    {
        
for(i = 1; i <= N; i++)
            scanf(
"%s"&mp[i][1]);
        
for(i = 0; i <= N + 1; i++)
            mp[i][
0= mp[i][M + 1= '.';
        
for(i = 0; i <= M + 1; i++)
            mp[
0][i] = mp[N + 1][i] = '.'
        
int count = 0;
        
for(i = 1; i <= N; i++)
            
for(j = 1; j <= M; j++)
                
if(mp[i][j] == 'W')
                {
                    count
++;
                    DFS(i, j);
                }
        printf(
"%d\n", count);
    }
    
//system("pause");
}
深度优先遍历,栈实现:

#include<stdio.h>
#include
<stdlib.h>// stack;
#include<string.h>
#define LEN 110
#define LEN1  10010
typedef 
struct
{
    
int x;
    
int y;
}Point;
Point stk[LEN1];
int tp;
char mp[LEN][LEN];
int N, M;
int d[8][2= {-1-1-10-110-1011-11011};
void DFS(int x0, int y0)
{
    
int i, j;
    stk[
0].x = x0;
    stk[
0].y = y0;
    mp[x0][y0] 
= 'X';
    tp 
= 1;
    
while(tp != 0)
    {
        
for(i = 0; i < 8; i++)
        {
            
int x1 = stk[tp - 1].x + d[i][0];
            
int y1 = stk[tp - 1].y + d[i][1];
            
if(mp[x1][y1] == 'W')
            {
                mp[x1][y1] 
= 'X';
                stk[tp].x 
= x1;
                stk[tp
++].y = y1;
                
break;
            }
        }
        
if(i >= 8)
            tp
--;
    }
}
int main() 
{
    
int i, j;
    
while(scanf("%d%d"&N, &M) != EOF)
    {
        
for(i = 1; i <= N; i++)
            scanf(
"%s"&mp[i][1]);
        
for(i = 0; i <= N + 1; i++)
            mp[i][
0= mp[i][M + 1= '.';
        
for(i = 0; i <= M + 1; i++)
            mp[
0][i] = mp[N + 1][i] = '.'
        
int count = 0;
        
for(i = 1; i <= N; i++)
            
for(j = 1; j <= M; j++)
                
if(mp[i][j] == 'W')
                {
                    count
++;
                    DFS(i, j);
                }
        printf(
"%d\n", count);
    }
    
//system("pause");
}
广度优先遍历:

#include<stdio.h>
#include
<stdlib.h>
#include
<string.h>// queue
#define LEN 110
#define LEN1  10010
typedef 
struct
{
    
int x;
    
int y;
}Point;
Point q[LEN1];
int f, r;
char mp[LEN][LEN];
int N, M;
int d[8][2= {-1-1-10-110-1011-11011};
void BFS(int x0, int y0)
{
    
int i, j;
    q[
0].x = x0;
    q[
0].y = y0;
    mp[x0][y0] 
= 'X';
    f 
= 0;
    r 
= 1;
    
while(f != r)
    {
        
int x = q[f].x;
        
int y = q[f].y;
        f
++;
        
for(i = 0; i < 8; i++)
        {
            
int x1 = x + d[i][0];
            
int y1 = y + d[i][1];
            
if(mp[x1][y1] == 'W')
            {
                mp[x1][y1] 
= 'X';
                q[r].x 
= x1;
                q[r
++].y = y1;
            }
        }
    }
}
int main() 
{
    
int i, j;
    
while(scanf("%d%d"&N, &M) != EOF)
    {
        
for(i = 1; i <= N; i++)
            scanf(
"%s"&mp[i][1]);
        
for(i = 0; i <= N + 1; i++)
            mp[i][
0= mp[i][M + 1= '.';
        
for(i = 0; i <= M + 1; i++)
            mp[
0][i] = mp[N + 1][i] = '.'
        
int count = 0;
        
for(i = 1; i <= N; i++)
            
for(j = 1; j <= M; j++)
                
if(mp[i][j] == 'W')
                {
                    count
++;
                    BFS(i, j);
                }
        printf(
"%d\n", count);
    }
    
//system("pause");

你可能感兴趣的:(poj2386--图的遍历)