最小生成树
一个有 n 个结点的连通图的最小生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的权值总和最小的边。
刘汝佳<<训练指南>>P343详细介绍了最小生成树相关的知识。
下面直接给出Kruskal算法的模板:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 100 + 10;
const int maxm = 100 * 100 + 10;
struct Edge//边
{
int u, v;
int dist;
Edge(int u, int v, int d): u(u), v(v), dist(d) {}
bool operator<(const Edge&rhs)const
{
return dist < rhs.dist;
}
};
struct Kruskal
{
int n, m; //点数,边数
vector<Edge> edges;//边列表
int fa[maxn]; //并查集
int findset(int x){ return fa[x] == -1 ? x : fa[x] = findset(fa[x]); }
void init(int n)
{
this->n = n;
m = 0;
memset(fa, -1, sizeof(fa));
edges.clear();
}
void AddEdge(int u, int v, int dist)
{
edges.push_back(Edge(u, v, dist));
m=edges.size();
}
int kruskal()
{
int sum = 0; //最小生成树权值
int cnt = 0; //最小生成树边数目
sort(edges.begin(), edges.end());
for(int i = 0; i < m; i++)
{
int u = edges[i].u, v = edges[i].v;
if(findset(u) != findset(v))
{
sum += edges[i].dist;
fa[findset(u)] = findset(v);
if(++cnt >= n - 1) break;
}
}
//注意n==0时应该输出0,当最小生成树不存在时,输出-1
return cnt>=n-1?sum:-1;
}
}KK;
最小生成树应用
POJ 2349Arctic Network(最小生成树思想):题意挺坑的。解题报告!
POJ 2031Building a Space Station(最小生成树):基本应用。解题报告!
POJ 1679The Unique MST(次小生成树):求次小生成树。解题报告!
POJ 1751Highways(最小生成树):最小生成树简单题。解题报告!
POJ 2075Tangled in Cables(最小生成树):模板题。解题报告!
POJ 2485Highways(最小生成树):模板题。解题报告!
POJ 1789Truck History(最小生成树):解题报告!
POJ 2395Out of Hay(最小瓶颈生成树):最小瓶颈生成树。解题报告!
POJ 2377Bad Cowtractors(最大生成树):最大生成树。解题报告!
POJ 2421Constructing Roads(简单最小生成树):解题报告!
POJ 1258Agri-Net(最小生成树):解题报告!
POJ 1251Jungle Roads(最小生成树简单题):解题报告!
POJ 3625Building Roads(最小生成树):解题报告!
POJ 1287Networking(最小生成树):解题报告!
POJ 1861Network(最小瓶颈生成树):解题报告!
POJ 3723Conscription(最大生成树):解题报告!
POJ 1797Heavy Transportation(最大生成树):解题报告!
HDU 1879继续畅通工程(最小生成树):解题报告!
HDU 1863畅通工程(最小生成树):解题报告!
HDU 1875畅通工程再续(最小生成树):解题报告!
HDU 1233还是畅通工程(最小生成树入门):解题报告!
HDU 4750Count The Pairs(最小生成树): 解题报告!
HDU 3371Connect the Cities(最小生成树):解题报告!
HDU 1162Eddy's picture(最小生成树):解题报告!