图论之DFS与BFS

深度优先搜索(BFS)与广度优先搜索(DFS)是图遍历中的二大重要方法。其中BFS主要用于遍历或搜索图、树及走迷宫等回溯问题中。而DFS则通常用于求起点到终点的最短路径及求两点间最优路径的问题

一、BFS

我们首先来看一下对于一个无向图来说,BFS的遍历过程如下:
图论之DFS与BFS_第1张图片
由上图我们可以看出,对于上述图,我们BFS的遍历结果为 ADFEBC。显然,我们可以利用一个递归或者是栈来实现这种访问方式,代码如下:

#define MAX 100

bool visited[MAX];

typedef struct
{
    int n,e;
    int vex[MAX];
    int edge[MAX][MAX];
 
}LJJZ;

//深度优先遍历递归算法
void DfsTraverse(ALGraph G) 
{
	 int v; 
	 for(v=1;v<=G.vexnum;v++)
	 {
	 	 visited1[v]=0; 
	 }
	 for(v=1;v<=G.vexnum;v++) 
	 {
	 	 if(!visited1[v]) 
	 	 	Dfs(G,v); 
	 }
}

void Dfs(ALGraph G,int v) 
{
	 ArcNode *p; 
	 int w; 
	 visited1[v]=1; 
	 printf("%c",G.vertices[v].data); 
	 p=G.vertices[v].firstarc;
	 while(p) 
	 {
	 	 w=p->adjvex; 
	 	 if(!visited1[w]) 
	 	 	Dfs(G,w); 
	 	 	p=p->nextarc;	 	 
	 } 
}

下面我们再看一道题
图论之DFS与BFS_第2张图片
题目如上,解法很简单,对所有结点遍历,每遇到一个没有访问过的结点就直接DFS遍历,然后在访问下一个结点,因为DFS遍历过程中会对访问过的结点做一个标记,因此第一次DFS遍历之后所有访问过的结点都有标记,那么每次对没有标记的那就一定没有遍历过,即该节点与上次DFS遍历的结点不同,因此,我们每次遇到没有访问过的结点,那就一定表示该区域与上一区域并不连通,因此只要让当前结点与前一个区域任意结点之间有一座桥就可以使他们连通。
综上所述,我们只要做一个计数器,每次DFS的时候,就使计数器+1,最后直接输出计数器即可。
AC代码如下:

#include"bits/stdc++.h"
#include"stack"
#include"queue"
#include"vector"
using namespace std;

#define max_n 1010

// struct edge{
//     int v,next ;
// }e[max_n];

vector<int> adj[max_n];
// int p[max_n],x=0;
int a=0;
bool visited[max_n];

void init()
{
    memset(visited,0,sizeof(visited));
    // memset(p,-1,sizeof(p));
}

int dfs(int pos)
{
    stack<int> S;
    visited[pos]=true;
    S.push(pos);
    a++;
    while(!S.empty())
    {
        int now =S.top();
        // cout<<"now: "<
        S.pop();
        if(!visited[now])
        {
            visited[now] =true;
            a++;    
        }
        vector<int>::iterator it = adj[now].begin();
        while(it != adj[now].end())
        {
            if(!visited[*it])
            {
                S.push(*it);
            }   
            it++;
        }
    }
    return a;
}

int main()
{
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    init();
    int num[max_n];
    memset(num,0,sizeof(num));
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
        num[x]++;
        num[y]++;
    }
    int maxnum=0;
    dfs(1);
    for(int i=1;i<n;i++)
    {
       if(!visited[i])
       {
            dfs(i);
            maxnum++;
       }
    }
    cout<<maxnum<<endl;
    return 0;
}

二、BFS

BFS是层次遍历,一般可用队列来实现,其遍历规则如下:
图论之DFS与BFS_第3张图片
遍历结果为:ADEBFC,显然,这是一个层次遍历的,那么层次遍历最早遍历到的到某一既定结点这个遍历路径即为从起点到给定终点的最短路径。
算法代码如下:

//广度优先收索
void bfs(LJJZ m,int v)
{
    queue<int> q;
    visited[v]=1;
    cout<<m.vex[v]<<" ";
    q.push(v);
    while(!q.empty())
    {
       int x;
       x=q.front();
       q.pop();
       for(int j = 0;j<m.n;j++)
       {
           if(m.edge[x][j]==1 && !visited[j])
           {
               visited[j]=true;
               cout<<m.vex[j]<<" ";
               q.push(j);
          }
       }
    }
}

你可能感兴趣的:(算法练习)