📌  相关文章
📜  使用STL的无向图的连接组件的唯一长度的计数(1)

📅  最后修改于: 2023-12-03 15:06:54.295000             🧑  作者: Mango

使用STL的无向图的连接组件的唯一长度的计数

在计算机科学领域中,图(Graph)是一种非常有用的数据结构,用于表示各种对象之间的关系。无向图是一个由一些点和边所组成的结构,其中没有方向。在无向图中,连接在一起的点被称为一个连通组件。本篇文章将介绍如何使用STL中的无向图实现连接组件的唯一长度的计数。

使用无向图解决问题的步骤

使用STL实现无向图的连接组件唯一长度计数,以下是解决问题的步骤:

  1. 定义一个无向图:使用STL实现一个无向图,并添加必要的点和边。

  2. 找到连通组件:使用DFS或BFS遍历无向图,并查找所有连通组件。

  3. 计算唯一长度:对于每个连通组件,计算它的唯一长度。

  4. 返回结果:将所有连接组件的唯一长度相加,返回结果。

接下来,我们将分别介绍这些步骤。

定义一个无向图

使用STL定义无向图非常简单,只需使用vectormap类型。

#include <iostream>
#include <vector>
#include <map>

using namespace std;

class Graph {
private:
    map<int, vector<int>> adjacency_list;  // 用邻接表表示图

public:
    void addEdge(int v, int w) {
        adjacency_list[v].push_back(w);  // 将w添加到v的邻接列表中
        adjacency_list[w].push_back(v);  // 将v添加到w的邻接列表中
    }

    vector<int> getAdjacencyList(int v) {
        return adjacency_list[v];  // 获取v的邻接列表
    }
};

以上代码实现了一个简单的无向图。通过addEdge()方法可以向图中添加边。使用getAdjacencyList()方法可以获取给定点的邻接列表。

找到所有的连通组件

要找到所有的联通组件,我们需要遍历无向图。以下代码使用DFS(深度优先遍历)方法完成此操作。

void DFSUtil(int v, map<int, bool>& visited) {
    visited[v] = true;

    cout << v << " ";  // 输出v

    vector<int> adj = adjacency_list[v];
    for (int i = 0; i < adj.size(); i++) {
        if (!visited[adj[i]]) {
            DFSUtil(adj[i], visited);  // 递归遍历邻接节点
        }
    }
}

void DFS(int v) {
    map<int, bool> visited;

    // 标记所有节点为未访问
    for (auto i : adjacency_list)
        visited[i.first] = false;

    // 从v开始遍历
    DFSUtil(v, visited);
}

以上代码中,DFSUtil()方法是递归函数,它遍历给定节点的所有邻接节点。DFS()方法从给定的起始节点开始,遍历整个无向图。

计算唯一长度

对于每个连接组件,我们需要计算它的唯一长度。以下是实现这一步骤的代码:

int uniqueLength(int v, int w, int len, map<pair<int, int>, bool>& visited) {
    visited[{v, w}] = true;
    visited[{w, v}] = true;  // 标记v和w之间的连接已经访问过了

    int result = len;  // 初始化结果为给定的长度

    vector<int> adj = adjacency_list[w];
    for (int i = 0; i < adj.size(); i++) {
        if (!visited[{w, adj[i]}]) {
            result += uniqueLength(w, adj[i], len + 1, visited);  // 递归调用uniqueLength,并增加长度
        }
    }

    return result;
}

以上代码使用递归计算给定节点之间的唯一长度。使用visited 来跟踪已经访问过的连接,防止重复计算。

返回结果

一旦我们找到了每个连接组件的唯一长度,就可以将它们相加并返回结果了。

int uniqueLengths() {
    int result = 0;
    map<pair<int, int>, bool> visited;

    // 遍历所有的点和边
    for (auto i : adjacency_list) {
        int v = i.first;

        vector<int> adj = i.second;
        for (int j = 0; j < adj.size(); j++) {
            int w = adj[j];

            // 如果v和w之间的连接没有被访问
            if (!visited[{v, w}]) {
                // 计算v和w之间的唯一长度
                int len = uniqueLength(v, w, 1, visited);
                result += len;
            }
        }
    }

    return result;
}

以上代码遍历图中的每个点和边,然后计算连接组件的唯一长度并将它们相加。visited跟踪已经访问过的连接,以确保将它们作为唯一长度计数。

结论

至此,我们已经学习了用STL实现无向图的连接组件唯一长度计数的方法。通过定义一个无向图、找到所有的连通组件、计算唯一长度,最后将它们相加,我们可以得到一个准确的计数。

完整代码见下:

#include <iostream>
#include <vector>
#include <map>

using namespace std;

class Graph {
private:
    map<int, vector<int>> adjacency_list;  // 用邻接表表示图

public:
    void addEdge(int v, int w) {
        adjacency_list[v].push_back(w);  // 将w添加到v的邻接列表中
        adjacency_list[w].push_back(v);  // 将v添加到w的邻接列表中
    }

    vector<int> getAdjacencyList(int v) {
        return adjacency_list[v];  // 获取v的邻接列表
    }
};

void DFSUtil(int v, map<int, bool>& visited) {
    visited[v] = true;

    cout << v << " ";  // 输出v

    vector<int> adj = adjacency_list[v];
    for (int i = 0; i < adj.size(); i++) {
        if (!visited[adj[i]]) {
            DFSUtil(adj[i], visited);  // 递归遍历邻接节点
        }
    }
}

void DFS(int v) {
    map<int, bool> visited;

    // 标记所有节点为未访问
    for (auto i : adjacency_list)
        visited[i.first] = false;

    // 从v开始遍历
    DFSUtil(v, visited);
}

int uniqueLength(int v, int w, int len, map<pair<int, int>, bool>& visited) {
    visited[{v, w}] = true;
    visited[{w, v}] = true;  // 标记v和w之间的连接已经访问过了

    int result = len;  // 初始化结果为给定的长度

    vector<int> adj = adjacency_list[w];
    for (int i = 0; i < adj.size(); i++) {
        if (!visited[{w, adj[i]}]) {
            result += uniqueLength(w, adj[i], len + 1, visited);  // 递归调用uniqueLength,并增加长度
        }
    }

    return result;
}

int uniqueLengths() {
    int result = 0;
    map<pair<int, int>, bool> visited;

    // 遍历所有的点和边
    for (auto i : adjacency_list) {
        int v = i.first;

        vector<int> adj = i.second;
        for (int j = 0; j < adj.size(); j++) {
            int w = adj[j];

            // 如果v和w之间的连接没有被访问
            if (!visited[{v, w}]) {
                // 计算v和w之间的唯一长度
                int len = uniqueLength(v, w, 1, visited);
                result += len;
            }
        }
    }

    return result;
}

int main() {
    Graph g;

    // 添加边
    g.addEdge(1, 2);
    g.addEdge(2, 3);
    g.addEdge(3, 4);
    g.addEdge(5, 6);

    int count = uniqueLengths();

    cout << "Count: " << count << endl;

    return 0;
}