BFS application: UVA1599 ideal path

Title Description:

Given an undirected graph with n points and m edges, each edge is painted with a color. Find a path from point 1 to point n to minimize the number of edges. On this premise, the color sequence of edges is the smallest. There may be self rings and heavy edges. The input ensures that there is at least one road connecting 1 and n.

Input: m+1 lines in total

The first line contains two integers: n and m.

In the next m lines, three integers ai, bi, ci separated by spaces in each line indicate that there is a road with color ci  between ai, bi .

Output: output two lines in total

The first line is a positive integer k, indicating that 1 to n need to pass through at least k edges.

The second line contains a positive integer separated by k spaces, representing the color of the edges passing from 1 to n.

Problem solving ideas:

         This problem can be divided into two questions: first, find the minimum number of edges between two nodes; Then, the path with the shortest color sequence is selected from all the paths with the least number of sides. It is suitable for BFS, reverse elevation and forward path finding.

Problem solving steps:

Reverse elevation:

        1. Store the undirected graph with a chained forward star, start from n, reverse breadth first traversal, and calculate the elevation of each node;

        2. The height of 1 is the minimum number of sides from 1 to n, that is, the first question of the question.

int head[maxn];
int high[maxn];

class Edge
{
public:
    int to;
    int weight;
    int next;
};
Edge edge[maxm];

void InsertEgdg(int u, int v, int w)
{
    edge[++cnt].to = v;
    edge[cnt].weight = w;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

void CreateGraph()
{
    int u, v, w;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        cin >> u >> v >> w;
        InsertEgdg(u, v, w);
        InsertEgdg(v, u, w);
    }
}

void ReverseBFS()
{
    memset(high, 0, sizeof(high));
    int u = 0;
    high[n] = 0;
    visited[n] = true;
    q1.push(n);
    while (!q1.empty())
    {
        u = q1.front();
        q1.pop();
        for (int i = head[u]; i; i = edge[i].next)
        {
            if (visited[edge[i].to])
            {
                continue;
            }
            high[edge[i].to] = high[u] + 1;
            visited[edge[i].to] = true;
            q1.push(edge[i].to);

        }
    }
}

Forward path finding:

        1. First, three queues need to be established. q1 is used to save the adjacency point number required by BFS, q2 is used to save the minimum color number, and q3 is used to save the adjacency point number associated with the minimum edge of the color number sequence;

        2. Join the node with height - 1 in the adjacent point of 1, the node number such as q1 and the color number into q2;

        3. First, find out the minimum value of the color number of the spread circle: q1 and q2 are out of the queue synchronously, and save the subscript of the adjacency point of the smallest edge of the color number in q3. When finding the smallest edge of the color number, you can answer a blank of the second question, but at this time, the adjacency point corresponding to the smallest edge may not be unique.

 minw = 0x7fffffff;
        while (!q1.empty())  //Find the minimum value of the first cycle of diffusion
        {
            v = q1.front();
            q1.pop();
            w = q2.front();
            q2.pop();
            if (w < minw)   //Update color number minimum
            {
                while (!q3.empty())
                {
                    q3.pop();
                }
                minw = w;
            }
            if (w == minw)   //Put the same minimum value into the queue
            {
                q3.push(v);
            }
        }
        cout << minw << " ";

        4,   Continue to spread only at the adjacency point with the smallest color number sequence, find the adjacency point with height - 1 in q3, enter node number q1 and weight q2

Overall code implementation:

#include <iostream>
using namespace std;
#include <queue>
#define maxn 100000
#define maxm 200000

int n, m, w, cnt;
bool visited[maxn];
queue<int> q1, q2, q3; 
int head[maxn];
int high[maxn];

class Edge
{
public:
    int to;
    int weight;
    int next;
};
Edge edge[maxm];

void InsertEgdg(int u, int v, int w)
{
    edge[++cnt].to = v;
    edge[cnt].weight = w;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

void CreateGraph()
{
    int u, v, w;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        cin >> u >> v >> w;
        InsertEgdg(u, v, w);
        InsertEgdg(v, u, w);
    }
}

void ReverseBFS()
{
    memset(high, 0, sizeof(high));
    int u = 0;
    high[n] = 0;
    visited[n] = true;
    q1.push(n);
    while (!q1.empty())
    {
        u = q1.front();
        q1.pop();
        for (int i = head[u]; i; i = edge[i].next)
        {
            if (visited[edge[i].to])
            {
                continue;
            }
            high[edge[i].to] = high[u] + 1;
            visited[edge[i].to] = true;
            q1.push(edge[i].to);

        }
    }
}

void BFS()
{
    int u = 0, v = 0, w = 0;
    int minw = 0;
    memset(visited, false, sizeof(visited));
    visited[1] = true;
    for (int i = head[1]; i; i = edge[i].next)   //Find the height of 1 minus 1 adjacent contact
    {
        if (high[edge[i].to] == high[1] - 1)
        {
            q1.push(edge[i].to);
            q2.push(edge[i].weight);
        }
    }
    while (!q1.empty())
    {
        minw = 0x7fffffff;
        while (!q1.empty())  //Find the minimum value of the first cycle of diffusion
        {
            v = q1.front();
            q1.pop();
            w = q2.front();
            q2.pop();
            if (w < minw)   //Update color number minimum
            {
                while (!q3.empty())
                {
                    q3.pop();
                }
                minw = w;
            }
            if (w == minw)   //Put the same minimum value into the queue
            {
                q3.push(v);
            }
        }
        cout << minw << " ";
        while (!q3.empty())   //Continue to spread only at the adjacency point with the smallest color number sequence
        {
            u = q3.front();
            q3.pop();
            if (visited[u])
            {
                continue;
            }
            visited[u] = true;
            for (int i = head[u]; i; i = edge[i].next)
            {
                v = edge[i].to;
                if (high[v] == high[u] - 1)   //Spread only at the adjacent points of height - 1
                {
                    q1.push(v);
                    q2.push(edge[i].weight);
                }
            }
        }
    }
}

int main()
{
    CreateGraph();
    ReverseBFS();
    cout << high[1] << endl;
    BFS();
    cout << endl;

    return 0;
}

Tags: C++ Algorithm

Posted on Sat, 18 Sep 2021 04:54:54 -0400 by adamata