// 使用二叉堆优化的 Prim 算法。#include<cstring>#include<iostream>#include<queue>usingnamespace std;
constint N = 5050, M = 2e5 + 10;
structE {
int v, w, x;
} e[M * 2];
int n, m, h[N], cnte;
voidadde(int u, int v, int w){ e[++cnte] = E{v, w, h[u]}, h[u] = cnte; }
structS {
int u, d;
};
booloperator<(const S &x, const S &y) { return x.d > y.d; }
priority_queue<S> q;
int dis[N];
bool vis[N];
int res = 0, cnt = 0;
voidPrim(){
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0;
q.push({1, 0});
while (!q.empty()) {
if (cnt >= n) break;
int u = q.top().u, d = q.top().d;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
++cnt;
res += d;
for (int i = h[u]; i; i = e[i].x) {
int v = e[i].v, w = e[i].w;
if (w < dis[v]) {
dis[v] = w, q.push({v, w});
}
}
}
}
intmain(){
cin >> n >> m;
for (int i = 1, u, v, w; i <= m; ++i) {
cin >> u >> v >> w, adde(u, v, w), adde(v, u, w);
}
Prim();
if (cnt == n)
cout << res;
else cout << "No MST.";
return0;
}
#include<algorithm>#include<cstdio>structEdge {
int x, y, z;
};
int f[100001];
Edge a[100001];
intcmp(const Edge& a, const Edge& b){ return a.z < b.z; }
intfind(int x){ return f[x] == x ? x : f[x] = find(f[x]); }
intmain(){
int t;
scanf("%d", &t);
while (t--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) f[i] = i;
for (int i = 1; i <= m; i++) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
std::sort(a + 1, a + m + 1, cmp); // 先排序int num = 0, ans = 0, tail = 0, sum1 = 0, sum2 = 0;
bool flag = 1;
for (int i = 1; i <= m + 1; i++) { // 再并查集加边if (i > tail) {
if (sum1 != sum2) {
flag = 0;
break;
}
sum1 = 0;
for (int j = i; j <= m + 1; j++) {
if (a[j].z != a[i].z) {
tail = j - 1;
break;
}
if (find(a[j].x) != find(a[j].y)) ++sum1;
}
sum2 = 0;
}
if (i > m) break;
int x = find(a[i].x);
int y = find(a[i].y);
if (x != y && num != n - 1) {
sum2++;
num++;
f[x] = f[y];
ans += a[i].z;
}
}
if (flag)
printf("%d\n", ans);
elseprintf("Not Unique!\n");
}
return0;
}
#include<algorithm>#include<iostream>constint INF = 0x3fffffff;
constlonglong INF64 = 0x3fffffffffffffffLL;
structEdge {
int u, v, val;
booloperator<(const Edge &other) const { return val < other.val; }
};
Edge e[300010];
bool used[300010];
int n, m;
longlong sum;
classTr {
private:
structEdge {
int to, nxt, val;
} e[600010];
int cnt, head[100010];
int pnt[100010][22];
int dpth[100010];
// 到祖先的路径上边权最大的边int maxx[100010][22];
// 到祖先的路径上边权次大的边,若不存在则为 -INFint minn[100010][22];
public:
voidaddedge(int u, int v, int val){
e[++cnt] = (Edge){v, head[u], val};
head[u] = cnt;
}
voidinsedge(int u, int v, int val){
addedge(u, v, val);
addedge(v, u, val);
}
voiddfs(int now, int fa){
dpth[now] = dpth[fa] + 1;
pnt[now][0] = fa;
minn[now][0] = -INF;
for (int i = 1; (1 << i) <= dpth[now]; i++) {
pnt[now][i] = pnt[pnt[now][i - 1]][i - 1];
int kk[4] = {maxx[now][i - 1], maxx[pnt[now][i - 1]][i - 1],
minn[now][i - 1], minn[pnt[now][i - 1]][i - 1]};
// 从四个值中取得最大值 std::sort(kk, kk + 4);
maxx[now][i] = kk[3];
// 取得严格次大值int ptr = 2;
while (ptr >= 0 && kk[ptr] == kk[3]) ptr--;
minn[now][i] = (ptr == -1 ? -INF : kk[ptr]);
}
for (int i = head[now]; i; i = e[i].nxt) {
if (e[i].to != fa) {
maxx[e[i].to][0] = e[i].val;
dfs(e[i].to, now);
}
}
}
intlca(int a, int b){
if (dpth[a] < dpth[b]) std::swap(a, b);
for (int i = 21; i >= 0; i--)
if (dpth[pnt[a][i]] >= dpth[b]) a = pnt[a][i];
if (a == b) return a;
for (int i = 21; i >= 0; i--) {
if (pnt[a][i] != pnt[b][i]) {
a = pnt[a][i];
b = pnt[b][i];
}
}
return pnt[a][0];
}
intquery(int a, int b, int val){
int res = -INF;
for (int i = 21; i >= 0; i--) {
if (dpth[pnt[a][i]] >= dpth[b]) {
if (val != maxx[a][i])
res = std::max(res, maxx[a][i]);
else res = std::max(res, minn[a][i]);
a = pnt[a][i];
}
}
return res;
}
} tr;
int fa[100010];
intfind(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]); }
voidKruskal(){
int tot = 0;
std::sort(e + 1, e + m + 1);
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 1; i <= m; i++) {
int a = find(e[i].u);
int b = find(e[i].v);
if (a != b) {
fa[a] = b;
tot++;
tr.insedge(e[i].u, e[i].v, e[i].val);
sum += e[i].val;
used[i] = 1;
}
if (tot == n - 1) break;
}
}
intmain(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v, val;
std::cin >> u >> v >> val;
e[i] = (Edge){u, v, val};
}
Kruskal();
longlong ans = INF64;
tr.dfs(1, 0);
for (int i = 1; i <= m; i++) {
if (!used[i]) {
int _lca = tr.lca(e[i].u, e[i].v);
// 找到路径上不等于 e[i].val 的最大边权longlong tmpa = tr.query(e[i].u, _lca, e[i].val);
longlong tmpb = tr.query(e[i].v, _lca, e[i].val);
// 这样的边可能不存在,只在这样的边存在时更新答案if (std::max(tmpa, tmpb) > -INF)
ans = std::min(ans, sum - std::max(tmpa, tmpb) + e[i].val);
}
}
// 次小生成树不存在时输出 -1 std::cout << (ans == INF64 ? -1 : ans) << '\n';
return0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2023-07-28 AT_tenka1_2015_qualB_b 题解
2023-07-28 第十七节 图论 - 2
2023-07-28 CF709B 题解