\(kruskal\) 算法
struct Kruskal{
struct node{
int u, v;
i64 w;
bool operator<(const node &t) const {
return w < t.w;
}
};
int n, m, cnt;
i64 ans;
vector<node> edg;
Dsu dsu;
Kruskal(int n_, int m_) : edg(m_ + 1) {
cnt = 0;
ans = 0;
n = n_;
m = m_;
dsu = Dsu(n_);
init();
}
inline void init() {
for (int i = 1, u, v; i <= m; i++) {
i64 w;
std::cin >> u >> v >> w;
edg[cnt++] = {u, v, w};
}
sort(edg.begin(), edg.begin() + cnt);
}
inline void get_tree() {
int tot = 0;
for (int i = 0; i < cnt; i++) {
auto [u, v, w] = edg[i];
if (dsu.mergy(u, v)) {
tot++;
ans += w;
}
}
if (tot != n - 1) {
return false;
} else {
return true;
}
}
};
void solve() {
int n, m;
std::cin >> n >> m;
Kruskal ans(n, m);
ans.get_tree();
}
\(prim\) 算法:
struct prim{
struct node{
int to, nxt;
i64 w;
node() {}
node(int to, int nxt, i64 w = 1) : to(to), nxt(nxt), w(w) {}
};
struct S{
int u;
i64 dis;
bool operator<(const S& t) const {
return dis > t.dis;
}
};
int n, m, cnt, tot;
i64 ans;
vector<node> edg;
vector<int> head, vis;
vector<i64> dist;
prim(int n_, int m_) : edg(m_ << 1 | 1), head(n_ + 1), dist(n_ + 1, MOF), vis(n_ + 1) {
cnt = 0;
tot = 0;
ans = 0;
n = n_;
m = m_;
init();
}
inline void add(int u, int v, i64 w = 1) {
cnt++;
edg[cnt].to = v;
edg[cnt].nxt = head[u];
edg[cnt].w = w;
head[u] = cnt;
}
inline void init() {
for (int i = 1, u, v; i <= m; i++) {
i64 w = 1;
std::cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
}
inline void Prim() {
priority_queue<S> q;
q.push((S){1, 0});
dist[1] = 0;
// vis[1] = 1;
while (!q.empty()) {
if (tot >= n) {
break;
}
auto [u, dis] = q.top();
q.pop();
if (vis[u]) {
continue;
}
vis[u] = 1;
tot++;
ans += dis;
for (int i = head[u]; i; i = edg[i].nxt) {
i64 v = edg[i].to;
i64 w = edg[i].w;
if (w < dist[v]) {
// vis[v] = 1;
dist[v] = w;
q.push((S){v, w});
}
}
}
if (tot == n) {
cout << ans << '\n';
} else {
cout << "orz\n";
}
}
};
void solve() {
int n, m;
std::cin >> n >> m;
prim ans(n, m);
ans.Prim();
}