首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在c++中不使用双循环将对分组成多个集合

在c++中不使用双循环将对分组成多个集合
EN

Stack Overflow用户
提问于 2022-05-05 12:28:01
回答 1查看 58关注 0票数 1

数据有多个测试用例,其中包含来自图的未知点对,属于不同的组件(no )。组件也是动态的)。

我尝试使用向量来存储多个集合(对于每个组件),但是由于存在多个组件,它仍然需要另一个循环来将点放在不同的组件中。我得到了使用堆或树的建议,但我不知道如何实现。

在C++中,是否有一种不用使用双循环来查找no的方法。在最大的群体中的分数?需要一个时间复杂度比O(n^2)更好的解决方案。谢谢

例如,输入:

代码语言:javascript
运行
复制
{1,2}
{2,4}
{2,3}
{4,3}
{9,8}
{7,8}
{6,7}
{7,5}

总共有2组点{1,2,3,4}和{5,6,7,8,9},最大的组有5分。输出:5

另一个例子是:

代码语言:javascript
运行
复制
{1,2}
{2,3}
{8,9}
{6,7}
{7,8}
{4,5}

共有3组点{1,2,3},{4,5} & {6,7,8,9},最大的组有4分。输出:4

EN

回答 1

Stack Overflow用户

发布于 2022-05-05 14:13:12

在图中查找组件的标准算法是使用简单的图遍历算法。例如,您可以使用广度优先搜索或深度优先搜索。

首先,您必须将所提供的图形表示(称为边缘列表)转换为更适合于图遍历的结构。例如,您可以使用邻接列表,即映射每个节点到连接到的其他节点的列表的映射。

下面的示例完成了所有这些操作,并输出了最大组件中的节点数。

代码语言:javascript
运行
复制
int find_largest_component(const std::vector<std::pair<int,int>>& edge_list) {
    std::map<int, std::vector<int>> adjacency_list {};

    // build an adjecency list of the undirected graph
    for ( auto it : edge_list ) {
        adjacency_list[it.first].push_back(it.second);
        adjacency_list[it.second].push_back(it.first);
    }
    
    int component_count {0};
    int largest_component {0};

    // a queue for breadth first search
    std::queue<decltype(adjacency_list)::value_type> Q {};
    while ( !adjacency_list.empty() ) {

        // push a single node to queue and remove it from graph
        Q.push(std::move(*adjacency_list.begin()));
        adjacency_list.erase(adjacency_list.begin());

        while ( !Q.empty() ) {
            // pop a node from queue
            auto v = std::move(Q.front()); Q.pop();
            component_count++;

            // loop over neighbours
            for ( auto n : v.second ) {
                auto h = adjacency_list.find(n);
                if ( h != adjacency_list.end() ) {
                    // found a neighbour that is still in the graph
                    // (and thus not yes visited). Push it to the queue
                    // and remove it from the graph
                    Q.push(std::move(*h));
                    adjacency_list.erase(h);
                }
            }
        }

        // update the largest component count if we found a larger one
        if ( component_count > largest_component ) {
            largest_component = component_count;
        }
        component_count = 0;
    }

    return largest_component;
}

注意,虽然理论上纯宽度优先搜索是O(V+E),但我使用了std::map,它通常被实现为一棵红黑树。因此,这个解决方案并不是最佳的。如果您的节点可以连续编号,则可以使用std::vector而不是std::map作为邻接列表,并使用索引,而不是搜索查找节点。

您可以在哥德波特上找到一个活生生的例子

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72127188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档