图论 最小生成树
这个专题的难度就很友好 学过离散数学或数据结构的都了解最小生成树 就不多说了 算法原理基于贪心 很简洁 用并查集优化一下 最大复杂度就是排序的复杂度O(eloge) 比较模板 作为生成树的基础 熟练一下就好..
prim算法的代码就不贴了 复杂度O(n^2) 还没见有题卡O(eloge)不能过 O(n^2)能过的..但并查集那步优化很重要,有的题会卡
模板代码:
struct viia { int u, v; int w; }a[300005];
void add(int u, int v, int w)//t初始为1
{
a[t].u = u, a[t].v = v, a[t++].w = w;
}
int cmp(viia x, viia y)
{
return x.w < y.w;
}
int find(int x)
{
if (!f[x]) return x;
f[x] = find(f[x]);
return f[x];
}
int kru()
{
sort(a + 1, a + t, cmp);
int i, ans = 0, w, u, v, t1, t2, cnt = 0;
for (i = 1; i < t; i++)
{
u = a[i].u, v = a[i].v, w = a[i].w;
t1 = find(u), t2 = find(v);
if (t1 != t2)
f[t1] = t2, ans += w, cnt++;
if (cnt == t - 1) return ans;
}
return -1;
}
Poj 1287&&poj 1258&&hdu1233 裸最小生成树
Poj 2031 阅读理解 G++错 C++ac系列..(后来发现G++输出时要把%lf换成%f..)
Poj 1251 读题+读数据
Poj 2421 有一点变化的最小生成树 不难
Zoj 1586&&Poj 1789&& Poj 1751&&hdu1875 几乎没有变化的最小生成树
Poj 2349 阅读理解+有一点变化的最小生成树
Poj 3026 墙裂推荐 搜索加最小生成树 代码量较大 题意有点阅读理解的意思...其实就是求经过所有字母的连通图长度 就是最小生成树 题目有2个坑 x y之后有大量空格 读取数字后用gets()读掉整行 而且数据范围有误 至少开到102*102的数组存地图 其他都挺好
Poj 1679 墙裂推荐 求最小生成树是否唯一 直观的方法是求次小生成树 和次短路一样 依次去掉最短路中的某边 再求最短路 其中最短的是第二短路 按这种思想 kru求次小生成树的复杂度是O(ne) (因为排序只用1次)需要注意的是无向图删边需要删2个 如果是通过标记的方法删边 那么排序要用稳定排序stable_sort()以保持无向边的2条有向边在排序后仍然在一起 因为这个蜜汁wa好久
当然有复杂度更低的算法 第一次求最小生成树时将加入的边做标记 然后在排序 将标记过的边排在权相同的边的最末尾 再求一次最小生成树 如果和第一次的边完全一样 则最小生成树唯一 复杂度同最小生成树复杂度O(eloge)(可以过这题 但不一定能求出次小生成树的值)
顺便吐槽一下icpc2018徐州的最简单题,给出随机数构成树,求最小生成树个数,并详细介绍的生成树计数...表面是生成树计数,然而因为是随机数,最小生成树重复的概率很小,所以跑一下有没有最小生成树,有就1没有就0...好像1题最快有银牌,现场虽然很快看出,然而最小生成树代码居然调了一阵...1题铜..