克鲁斯卡尔
#include <cstdio> #include <algorithm> using namespace std; #define maxn 200005 #define ll long long int fa[maxn], n, m; struct Edge { int x; int y; int z; } edge[maxn]; bool cmp(Edge a,Edge b) { return a.z < b.z; } int Find(int x) { if(x==fa[x]) return x; else return fa[x] = Find(fa[x]); } int main() { scanf("%d%d", &n, &m); int ans = 0; for (int i = 1; i <= m;i++) { scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].z); } sort(edge + 1, edge + 1 + m,cmp); for (int i = 1; i <= n;i++) fa[i] = i; for (int i = 1; i <= m;i++) { int x = Find(edge[i].x); int y = Find(edge[i].y); if(x==y) continue; fa[x] = y; ans += edge[i].z; } printf("%d ",ans); system("pause"); }
普里姆
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define maxn1 100005 #define maxn2 3005 #define ll long long int a[maxn2][maxn2], d[maxn1], n, m, ans; bool vis[maxn2][maxn2]; void Prim() { memset(d, 0x3f, sizeof(d)); memset(vis, 0, sizeof(vis)); d[1] = 0; for (int i = 1; i < n;i++) { int x = 0; for (int j = 1; j <= n;j++) if(!vis[j]&&(x==0||d[j]<d[x])) x = j; vis[x] = 1; for (int y = 1; y <= n;y++) if(!vis[y]) d[y] = min(d[y], a[x][y]); } } int main() { scanf("%d%d", &n, &m); memset(a,0x3f,sizeof(a)); for (int i = 1; i <= n;i++) a[i][i] = 0; for (int i = 1; i <= m;i++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); a[x][y] = a[y][x] = min(z, a[x][y]); //有些题两点之间会有重边 } Prim(); for (int i = 2; i <= n;i++) ans += d[i]; printf("%d ", ans); }