// 建图 structEdge { int from, to, dis; Edge(int _from, int _to, int _dis) { from = _from; to = _to; dis = _dis; } }; std::vector<Edge> g[MAX_SIZE]; voidinsert(int u, int v, int w){ // 由于是无向图,所以要存两条边 g[u].push_back(Edge(u, v, w)); g[v].push_back(Edge(v, u, w)); }
// m是边数,n是节点数 int m, n; intprim(){ // now是选择的点,dis是now与其它点的距离,vis标记是否访问过 int ans = 0, now = 1, dis[MAX_SIZE]; bool vis[MAX_SIZE]; // 初始化 for (int i = 2; i <= n; ++i) { vis[i] = false; dis[i] = INF; for (int j = 0; j < int(g[i].size()); ++j) if (g[i][j].to == now) dis[i] = std::min(dis[i], g[i][j].dis); }
for (int i = 1; i < node; ++i) { int minn = INF; vis[now] = true; // 找到边权最小的边,更新now for (int j = 1; j <= n; ++j) { if (!vis[j] && minn > dis[j]) { minn = dis[j]; now = j; } } // 加上边权 ans += minn; // 更新dis for (int j = 1; j <= n; ++j) for (int k = 0; !vis[j] && k < int(g[now].size()); ++k) if (dis[g[now][k].to] > g[now][k].dis) dis[g[now][k].to] = g[now][k].dis; return ans; }
Edge g[MAX_SIZE]; int i = 0; voidinsert(int u, int v, int w){ ++i; g[i].from = u; g[i].to = v; g[i].dis = w; }
// 并查集 int fa[MAX_SIZE]; intfind(int u){ if (fa[u] == u) return u; return fa[u] = find(fa[u]); }
// 比较函数 boolcmp(Edge a, Edge b){ return a.dis < b.dis; } intkruskal(){ // tot记录边数 int ans = 0, tot = 0; // 排序 std::sort(g + 1, g + m + 1, cmp); for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 1; i <= m; ++i) { Edge<type> e = g[i]; // 判断是否连通 if (find(e.from) != find(e.to)) { ans += g[i].dis; fa[find(e.from)] = find(e.to); } // 如果已经形成最小生成树了就退出 if (++tot == edge - 1) break; } return ans; }