Prim
基于优先队列
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define INF 1e9
const int MAXN = 200005;
int n, m, ans;
struct edge
{
int v, w;
};
struct node
{
int dis, u;
bool operator>(const node &a) const
{
return dis > a.dis;
}
};
vector<edge> e[MAXN];
int d[MAXN], vis[MAXN];
bool prim(int s)
{
memset(vis, 0, sizeof(vis));
priority_queue<node, vector<node>, greater<node>> q;
int cnt = 0;
for (int i = 0; i <= n; i++)
d[i] = INF;
d[s] = 0;
q.push({0, s});
while (!q.empty())
{
int u = q.top().u;
q.pop();
if (vis[u])
continue;
vis[u] = 1; // 标记出圈
ans += d[u];
cnt++;
for (auto ed : e[u])
{
int v = ed.v, w = ed.w;
if (d[v] > w)
{
d[v] = w; // 到圈外任意一点的最小距离
q.push({d[v], v});
}
}
}
return cnt == n;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int u, v, w;
cin >> u >> v >> w;
e[u].push_back({v, w});
e[v].push_back({u, w});
}
if (prim(1))
cout << ans;
else
cout << "orz";
return 0;
}
Kruskal
基于并查集
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 200005;
struct edge
{
int u, v, w;
bool operator<(const edge &t) const
{
return w < t.w;
}
} e[MAXN];
int fa[MAXN];
int ans, n, m;
int find(int x)
{
return fa[x] == x ? x : (fa[x] = find(fa[x]));
}
bool kruskal()
{
int cnt = 0;
sort(e, e + m);
for (int i = 1; i <= n; i++)
fa[i] = i;
for (int i = 0; i < m; i++)
{
int x = find(e[i].u);
int y = find(e[i].v);
if (x != y)
{
fa[x] = y;
ans += e[i].w;
cnt++;
}
}
return cnt == n - 1;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
cin >> e[i].u >> e[i].v >> e[i].w;
if (kruskal())
cout << ans;
else
cout << "orz";
return 0;
}
P3366 [模板]最小生成树