Depth first traversal of numbers and graphs & breadth first traversal of trees and graphs

Posted by Dia:NL on Mon, 14 Feb 2022 11:56:29 +0100

Depth first traversal of trees and graphs & breadth first traversal of trees and graphs

The two traversal methods of tree and graph are algorithms based on the idea of dfs and bfs. Its idea is still recursive, but the traversal object becomes an undirected graph, so there are more precautions in the process of graph construction and search.

1, Depth first traversal of trees and graphs

Depth first traversal is similar to dfs, which traverses the branches in the tree and graph in turn.

1. Structure

Because it is an undirected graph, it is different from ordinary trees. First, look at the code:

int e[N],ne[N],h[M];//M = 2 * N;
int idx;

void daa(int a,int b)
{
    e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}

When entering:

int a,int b;
cin >> a >> b;
add(a,b),add(b,a);

Because it is an undirected graph, it needs to add twice. A closer look shows that the add function is similar to the function of inserting the header node of a single linked list. The following is the code of inserting the header node of a single linked list:

void head_add(int x)
{
    e[idx] = x,ne[idx] = head,head = idx++;  
}

Just replace the head with an h array.

In undirected graphs, h and NE arrays play similar but different roles. H is the pointer to the child node, which is used for the recursive part; When ne searches to the end, it jumps back to the pointer of another child node of the previous bifurcation for circulation.

2. Traversal

Code of dfs function:

void dfs(int u)
{
    vis[u] = 1;
    
    for(int i = h[u];i != -1;i = ne[i])
    {
        int j = e[i];
        if(vis[j])continue;
        
        int s = dfs(j);
    }
}

When facing different problems, you can make certain modifications.

3. Example code

Here is an example: 846. The center of gravity of the tree - AcWing question bank

The code is as follows:

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e5 + 3, M = N * 2;

int n, e[M], ne[M], h[N], idx;
bool vis[N];
int ans = N;

void add(int a, int b)
{
	e[idx] = a, ne[idx] = h[b], h[b] = idx++;
}

int dfs(int u)
{
	vis[u] = 1;

	int sum = 1, rex = 0;
	for (int i = h[u]; i != -1; i = ne[i])
	{
		int j = e[i];
		if (vis[j]) continue;

		int s = dfs(j);

		rex = max(rex, s);
		sum += s;
	}

	rex = max(rex, n - sum);
	ans = min(ans, rex);

	return sum;
}

int main()
{
	memset(h, -1, sizeof h);
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		add(a, b), add(b, a);
	}
	dfs(1);
	cout << ans << endl;
	return 0;
}

2, Breadth first traversal of trees and graphs

The idea of breadth first traversal is similar to bfs, which searches layer by layer.

1. Build

The construction method is the same as depth first traversal

2. Traversal

Breadth first traversal is the search for the edge, and the code is as follows:

void bfs()
{
    int hh = 0,tt = 0;
    q[0] = 1;//Queue array
    
    while(hh <= tt)
    {
        int t = q[hh++];
        
        for(int i = h[t];i != -1;i = ne[i])
        {
            int j = e[i];
            if(judge)
                q[++tt] = j;
        }
    }
    
}

Its basic template is like this. If you want to achieve different results, you can fill in the corresponding code.

3. Example code

Such as: 847. The level of the point in the figure - AcWing question bank

The code is as follows:

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e5 + 3,M = N * 2;

int n,m,idx;
int e[M],ne[M],h[N];
int q[N],d[N];

void add(int a,int b)
{
    e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}

int bfs()
{
    int hh = 0,tt = 0;
    q[0] = 1;
    
    memset(d,-1,sizeof d);
    d[1] = 0;
    
    while(hh <= tt)
    {
        int t = q[hh++];
        
        for(int i = h[t];i != -1;i = ne[i])
        {
            int j = e[i];
            
            if(d[j] == -1)
            {
                q[++tt] = j;
                d[j] = d[t] + 1;
            }
        }
    }
    
    return d[n];
}

int main()
{
    scanf("%d%d",&n,&m);
    
    memset(h,-1,sizeof h);
    
    for(int i = 0;i < m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
    }
    
    cout << bfs() << endl;
    return 0;
}

Topics: C++ Algorithm Graph Theory