structEdge { int from, to, cost; Edge(int u, int v, int w):from(u), to(v), cost(w) {} }; structHeapNode { int d, u; // d表示点u到MST的距离 booloperator< (const HeapNode& rhs) const { return d > rhs.d; // 小根堆 } }; vector<Edge> edges; // edges存所有边 vector<int> G[MAXN]; // G[i]是顶点i发出的所有边 bool done[MAXN]; // i是否已经加入了MST int d[MAXN]; // 每个点到MST的最小距离 intPrim(){ priority_queue<HeapNode> Q; int ans = 0; // 总权值 for (int i = 0; i < V; ++i) d[i] = INF; // V是图的节点数 d[0] = 0; // 从点0开始 memset(done, 0, sizeof(done)); Q.push((HeapNode){0, 0}); while (!Q.empty()) { HeapNode x = Q.top(); Q.pop; int u = x.u; // u为队头元素的序号 if (done[u]) continue; // 已经在MST中就跳过 ans += x.d; // 加上出队的队头元素到MST的距离 done[u] = true; for (int i = 0; i < G[u].size; ++i) { // 更新最小生成树的权值 Edge& e = edges[G[u][i]]; // 顶点to能修改最小距离 if (d[e.to] > e.cost) { d[e.to] = e.cost; Q.push((HeapNode){d[e.to], e.to}); } } } return ans; }
注意
本段代码用邻接表来存图,输入可以使用
1 2 3 4 5 6 7 8
for (int i = 0; i < E; ++i) { // E是边数 int u, v, cost; cin >> u >> v >> cost; // 输入边的起点、终点和权值 G[u].push_back(i); // 存储边的索引 edges.push_back(Edge(u, v, cost)); G[v].push_back(i); // 存储边的索引 edges.push_back(Edge(v, u, cost)); }
intKruskal(int V, int E){ sort(es, es + E, cmp); // 按权值从小到大排序 init_union_find(V); // 并查集初始化 int res = 0; for (int i = 0; i < E; ++i) { edge e = es[i]; if (!same(e.u, e.v)) { // u和v不属于一个集合 unite(e.u, e.v); // 合并u和v集合的元素 res += e.cost; } } return res; }