用户:
不知道该叫啥的一只萌新查看:2 回复:3 评论:2 创建时间:2024-07-09T22:22:43
洛谷题号:U441275
题目大意:给定n个点,求n阶完全图的最小生成树
感觉可以建图然后跑一遍tarjan最后统计边权,来问问这种思路对不对
「Origin、拾柒」在图中,特别是完全图中(即每对顶点之间都有一条边的图),最小生成树的概念其实有些特殊,因为对于n阶完全图来说,其所有边都参与构成了图的连通性。但是,如果我们从权重的角度来考虑,并假设图中的每条边都有一个权重,那么我们可以找到一种方式来定义“最小生成树”。
在一般情况下,我们假设完全图的每条边都有一个权重,并且我们希望找到一棵包含n-1条边且总权重最小的树,这n-1条边连接了所有的n个顶点。
为了找到这样的最小生成树,我们可以使用类似于Prim算法或Kruskal算法的方法,但在这里,由于是完全图,我们可以简单地通过排序边的权重并选择权重最小的n-1条边来构造最小生成树。
以下程序演示了如何找到完全图的最小生成树(假设边的权重存储在二维数组中)(c++):
#include <iostream>
#include <vector>
#include <algorithm>
// 假设边的结构如下,其中from和to表示边的两个顶点,weight表示边的权重
struct Edge {
int from, to, weight;
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
std::vector<Edge> findMST(int n, const std::vector<std::vector<int>>& weights) {
std::vector<Edge> edges;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
edges.emplace_back(Edge{i, j, weights[i][j]});
}
}
// 对边进行排序
std::sort(edges.begin(), edges.end());
// 选择前n-1条边作为最小生成树的边
std::vector<Edge> mstEdges(edges.begin(), edges.begin() + n - 1);
return mstEdges;
}
int main() {
int n;
std::cout << "Enter the number of vertices (n): ";
std::cin >> n;
std::vector<std::vector<int>> weights(n, std::vector<int>(n, 0));
std::cout << "Enter the weights of the edges (0 for non-existing edges):\n";
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i != j) {
std::cin >> weights[i][j]; // 注意:weights[i][i]应为0,因为不存在自环
// weights[j][i] = weights[i][j]; // 对于无向图,这行代码也是必要的
}
}
}
std::vector<Edge> mstEdges = findMST(n, weights);
std::cout << "Edges of the minimum spanning tree:\n";
for (const auto& edge : mstEdges) {
std::cout << "From " << edge.from << " to " << edge.to << " with weight " << edge.weight << std::endl;
}
return 0;
}
注意:在这个示例中,我们假设了完全图是无向的,并且边的权重是对称的(即weights[i][j] = weights[j][i])。如果输入的图是有向的,或者边的权重不是对称的,那么你可能需要稍微修改代码以适应这些情况。
点赞0
评论