山东大学数据结构实验13 最小生成树
Prime算法
描述
使用prim算法实现最小生成树
格式
输入
第一行两个整数n,e。n (
接下来e行,每行代表一条边:
i j w
表示顶点i和顶点j之间有一条权重为w的边
输出
最小生成树所有边的权重和
样例
输入
7 12
1 2 9
1 5 2
1 6 3
2 3 5
2 6 7
3 4 6
3 7 3
4 5 6
4 7 2
5 6 3
5 7 6
6 7 1
输出
16
限制
1s, 10240KiB for each test case.
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include<cstdio>
//from yuanzi
//prim
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 10;
int n, m;
int dist[N];
bool st[N];
struct graphNode {
int element;
graphNode *next;
int weight;
graphNode(int e, graphNode *node, int w) {
element = e;
next = node;
weight = w;
}
};
struct graphChain {
graphNode *firstNode;
graphNode *lastNode;
};
class graph {
public:
graph(int num = 0) {
node = num;
edge = 0;
aList = new graphChain[node + 1];
for (int i = 0; i <= node; i++) {
aList[i].firstNode = nullptr;
}
}
~graph() { delete[]aList; }
void insert(int v1, int v2, int w);
long long prim();
private:
int node;//the number of node
int edge;//the number of edge
graphChain *aList;
};
void graph::insert(int v1, int v2, int w) {
if (aList[v1].firstNode == nullptr) { aList[v1].firstNode = aList[v1].lastNode = new graphNode(v2, nullptr, w); }
else {
aList[v1].lastNode->next = new graphNode(v2, nullptr, w);
aList[v1].lastNode = aList[v1].lastNode->next;
}
}
long long graph::prim() {
long long res = 0;
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;//小根堆初始化
heap.push({0, 1});
while (!heap.empty()) {
auto t = heap.top();
heap.pop();
int ver = t.second, distance = t.first;
if (st[ver]) continue;
st[ver] = true;
dist[ver] = 0;
res += distance;
for (graphNode *Node = aList[ver].firstNode; Node; Node = Node->next) {
int j = Node->element;
if (dist[j] > Node->weight) {
dist[j] = Node->weight;
}
if (!st[j]) heap.push({dist[j], j});
}
}
return res;
}
int main() {
scanf("%d%d", &n, &m);
int v1, v2, c;
graph a(n);
while (m--) {
cin >> v1 >> v2 >> c;
a.insert(v1, v2, c);
a.insert(v2, v1, c);
}
cout << a.prim() << endl;
return 0;
}
克鲁斯卡尔算法
(不开long long见祖宗)
描述
使用kruskal算法实现最小生成树
格式
输入
第一行两个整数n,e。n (
接下来e行,每行代表一条边:
i j w
表示顶点i和顶点j之间有一条权重为w的边
输出
最小生成树所有边的权重和
样例
输入
7 12
1 2 9
1 5 2
1 6 3
2 3 5
2 6 7
3 4 6
3 7 3
4 5 6
4 7 2
5 6 3
5 7 6
6 7 1
输出
16
限制
1s, 10240KiB for each test case.
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 200010, M = 500010;
int p[N];
struct Edge {
int a, b, w;
bool operator<(const Edge &W) const {
return w < W.w;
}
};
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}//找到并查集的祖宗,并且进行路径压缩优化
class graph {
public:
graph(int num, int point) {
edges = new Edge[num];
this->num = num;
this->point = point;
}
long long kruskal();
void set(int a, int b, int w, int i) {
edges[i] = {a, b, w};
}
private:
int n;
int num;
int point;
struct Edge *edges;
};
long long graph::kruskal() {
sort(edges, edges + num);
for (int i = 1; i <= point; i++) p[i] = i; // 初始化并查集
long long res = 0;
for (int i = 0; i < num; i++) {
int a = edges[i].a,
b = edges[i].b,
w = edges[i].w;
a = find(a), b = find(b);
if (a != b) {
p[a] = b;
res += w;
}
}
return res;
}
int main() {
int n, m;
cin >> n >> m;
graph g(m, n);
for (int i = 0; i < m; i++) {
int a, b, w;
cin >> a >> b >> w;
g.set(a, b, w, i);
}
cout << g.kruskal() << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)