Kruskal (克鲁斯卡尔)算法(加边法)
时间复杂度O(mlog(m)),用并查集维护
模板代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=2e5+10;;
struct node {
int x,y,z;
}edge[maxn];
bool cmp(node a,node b) {
return a.z < b.z;
}
int fa[maxn];
int n,m;
int u,v,w;
long long sum;
int Find(int x) {
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
void solve() {
// Kruskal 算法求最小生成树
cin>>n>>m;
for(int i = 1; i <= m; i ++) {
cin>>edge[i].x>>edge[i].y>>edge[i].z;
}
for(int i = 0; i <= n; i ++) {
fa[i] = i;
}
sort(edge + 1,edge + 1 + m,cmp);
// 每次加入一条最短的边
for(int i = 1; i <= m; i ++) {
int x = Find(edge[i].x);
int y = Find(edge[i].y);
if(x == y) continue;
fa[y] = x;
sum += edge[i].z;
}
int ans = 0;
for(int i = 1; i <= n; i ++) {
if(i == fa[i]) ans ++;
}
if(ans > 1) puts("impossible");
else printf("%lld\n",sum);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
// cout<<"YES";
while (t--) {
// init();
solve();
}
return 0;
}
prim(普里姆)算法(加点法)
此处是暴力prim,复杂度达到O(n^2+m)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=505;;
int a[maxn][maxn];
int vis[maxn],dist[maxn];
int n,m;
int u,v,w;
long long sum = 0;
int prim(int pos) {
dist[pos] = 0;
// 一共有 n 个点,就需要 遍历 n 次,每次寻找一个权值最小的点,记录其下标
for(int i = 1; i <= n; i ++) {
int cur = -1;
for(int j = 1; j <= n; j ++) {
if(!vis[j] && (cur == -1 || dist[j] < dist[cur])) {
cur = j;
}
}
// 这里需要提前终止
if(dist[cur] >= inf) return inf;
sum += dist[cur];
vis[cur] = 1;
for(int k = 1; k <= n; k ++) {
// 只更新还没有找到的最小权值
if(!vis[k]) dist[k] = min(dist[k],a[cur][k]);
}
}
return sum;
}
void solve() {
// prim 算法求最小生成树
cin>>n>>m;
memset(a,0x3f,sizeof(a));
memset(dist,0x3f,sizeof(dist));
for(int i = 1; i <= m; i ++) {
cin>>u>>v>>w;
a[u][v] = min(a[u][v],w);
a[v][u] = min(a[v][u],w);
}
int value = prim(1);
if(value >= inf) puts("impossible");
else printf("%lld\n",sum);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
// cout<<"YES";
while (t--) {
// init();
solve();
}
return 0;
}