Kruskal 最小生成树的总结
2008-12-21 10:59
471 查看
写了3,4天的最小生成树,里边写了报告和没写的加起来也有十题左右了。发现这些简单的算法里头有不少的pin。特别是2421让人抓狂,bug一个接一个,wa了不下十数次后,在波波的指导下成功的ac了,后来自己又找到了原来程序的几个bug。
原先写这篇报告的时候以为Kruskal比Prim优秀许多。后来波波跟我说Prim也是很强的,于是我分别用Kruskal和Prim写了Poj1789,发现原来Prim也是很strong的,用的时间几乎只有Kruskal的20%,囧。于是现在把这篇报告改为Kruskal最小生成树总结,顺便把标程贴出来以后好找~~
下面的是Kruskal:
//这段代码用Kruskal来解决
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <algorithm>
using namespace std;
// 边类型
typedef struct Edge{
int x;
int y;
int weigh;
bool operator() ( Edge a,Edge b) {
return (a.weigh < b.weigh);
}
}Edge;
//最多可能的边
Edge edge[251001];
int parent[501];
//用于qsort()的比较函数
int compare(const void*a,const void *b)
{
return ((Edge*)a)->weigh - ((Edge*)b)->weigh;
}
// 找父节点并压缩路径
int Find(int x)
{
if( parent[x] >= 0)
parent[x] = Find(parent[x]);
else
return x;
return parent[x];
}
// 合并集合
void Union(int x,int y)
{
x = Find(x);
y = Find(y);
// 注意:这里的重边判断很重要
if( x == y)
return ;
if(parent[x] < parent[y])
parent[y] = x;
else
if(parent[x] > parent[y])
parent[x] = y;
else {
parent[x]--;
parent[y] = x;
}
}
int main()
{
int m,n;
int count = 0;
scanf("%d",&n);
for( int i = 0; i < n; i++) {
scanf("%d",&m);
memset(parent,-1,m * sizeof(int));
for( int j = 0; j < m; j++)
for( int k = 0; k < m; k++) {
scanf("%d",&edge[count].weigh);
edge[count].x = j;
edge[count++].y = k;
}
sort(edge,edge + m * m,Edge());
count = 1;
int max;
// 忽略那些为0的节点,有m个,然后从小到大去边
for( int j = m; j < (m * m) && count < m; j++)
if(Find(edge[j].x) != Find(edge[j].y)) {
count ++;
Union(edge[j].x,edge[j].y);
max = edge[j].weigh;
}
printf("%d/n",max);
}
}
唉,还是有parent好啊~~
原先写这篇报告的时候以为Kruskal比Prim优秀许多。后来波波跟我说Prim也是很强的,于是我分别用Kruskal和Prim写了Poj1789,发现原来Prim也是很strong的,用的时间几乎只有Kruskal的20%,囧。于是现在把这篇报告改为Kruskal最小生成树总结,顺便把标程贴出来以后好找~~
下面的是Kruskal:
//这段代码用Kruskal来解决
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <algorithm>
using namespace std;
// 边类型
typedef struct Edge{
int x;
int y;
int weigh;
bool operator() ( Edge a,Edge b) {
return (a.weigh < b.weigh);
}
}Edge;
//最多可能的边
Edge edge[251001];
int parent[501];
//用于qsort()的比较函数
int compare(const void*a,const void *b)
{
return ((Edge*)a)->weigh - ((Edge*)b)->weigh;
}
// 找父节点并压缩路径
int Find(int x)
{
if( parent[x] >= 0)
parent[x] = Find(parent[x]);
else
return x;
return parent[x];
}
// 合并集合
void Union(int x,int y)
{
x = Find(x);
y = Find(y);
// 注意:这里的重边判断很重要
if( x == y)
return ;
if(parent[x] < parent[y])
parent[y] = x;
else
if(parent[x] > parent[y])
parent[x] = y;
else {
parent[x]--;
parent[y] = x;
}
}
int main()
{
int m,n;
int count = 0;
scanf("%d",&n);
for( int i = 0; i < n; i++) {
scanf("%d",&m);
memset(parent,-1,m * sizeof(int));
for( int j = 0; j < m; j++)
for( int k = 0; k < m; k++) {
scanf("%d",&edge[count].weigh);
edge[count].x = j;
edge[count++].y = k;
}
sort(edge,edge + m * m,Edge());
count = 1;
int max;
// 忽略那些为0的节点,有m个,然后从小到大去边
for( int j = m; j < (m * m) && count < m; j++)
if(Find(edge[j].x) != Find(edge[j].y)) {
count ++;
Union(edge[j].x,edge[j].y);
max = edge[j].weigh;
}
printf("%d/n",max);
}
}
唉,还是有parent好啊~~
相关文章推荐
- 最小生成树基础总结(Prim Kruskal)
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- 最小生成树总结(prim、并查集和kruskal) C++实现
- 图论--最小生成树总结(Prim&&Kruskal)
- kruskal的最小生成树
- 关于最小生成树中的kruskal算法中判断两个点是否在同一个连通分量的方法总结
- 安慰奶牛 (Kruskal) (最小生成树)
- <最小生成树模板·kruskal> 村村通、繁忙的都市
- Kruskal模板求最小生成树
- hdu 1301(最小生成树kruskal)
- hdu-1863畅通工程 最小生成树克鲁斯卡尔算法kruskal(并查集实现)&&prim普利姆算法实现
- 最小生成树prim+kruskal模板
- Kruskal最小生成树
- C++实现矩阵图的遍历·最小生成树(prim,kruskal)·最短路径(Dijkstra,floyd)
- 【算法】最小生成树(Kruskal和Prim算法)
- HDU - 1102 Constructing Roads(最小生成树kruskal)
- 克鲁斯卡尔(Kruskal)算法求解最小生成树
- 图的广度遍历、深度遍历及最小生成树书算法(Prim、Kruskal)
- HDU - 1863 畅通工程(最小生成树kruskal)
- 最小生成树 kruskal()