数据有多个测试用例,其中包含来自图的未知点对,属于不同的组件(no )。组件也是动态的)。
我尝试使用向量来存储多个集合(对于每个组件),但是由于存在多个组件,它仍然需要另一个循环来将点放在不同的组件中。我得到了使用堆或树的建议,但我不知道如何实现。
在C++中,是否有一种不用使用双循环来查找no的方法。在最大的群体中的分数?需要一个时间复杂度比O(n^2)更好的解决方案。谢谢
例如,输入:
{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
另一个例子是:
{1,2}
{2,3}
{8,9}
{6,7}
{7,8}
{4,5}共有3组点{1,2,3},{4,5} & {6,7,8,9},最大的组有4分。输出:4
发布于 2022-05-05 14:13:12
在图中查找组件的标准算法是使用简单的图遍历算法。例如,您可以使用广度优先搜索或深度优先搜索。
首先,您必须将所提供的图形表示(称为边缘列表)转换为更适合于图遍历的结构。例如,您可以使用邻接列表,即映射每个节点到连接到的其他节点的列表的映射。
下面的示例完成了所有这些操作,并输出了最大组件中的节点数。
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作为邻接列表,并使用索引,而不是搜索查找节点。
您可以在哥德波特上找到一个活生生的例子
https://stackoverflow.com/questions/72127188
复制相似问题