最近在学二分图 那就先回顾下图论的几个基本算法吧
最小生成树---即最小权重生成树
权威定义:
在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得
的 w(T) 最小,则此 T 为 G 的
最小生成树。
今天我们先来讲下Kruskal算法(它不能处理权重为负的情况)
1.首先 这个算法第一步是要将图中所有的边进行排序 这个过程我们可以直接调用sort完成 不仅因为它方便 而且效率也不低
2.因为我们所要的生成树是权重最小的 所以排序是从小到大的 我们依次取出每条边(u,v)
3.这边的关键是加进边的时候 判断它的连通性:这里我们运用很强大的Union-Find-Set(并查集)
并查集 我这边并不想展开去谈 而且对于这个算法 我只是用到了它的最基础的路径压缩的查询函数
累了 刚和小伙伴们玩了好久 导致这个页面静止很久了…… 接下来 我就直接给出Kruskal的渣渣模板(你有任何疑问 去访问大牛的博客)--我这边纯粹是个人的回顾和输给同学的赌
该死的 排位连赢2盘 之后连输2盘 心情都没了 糟糕透了。。。。
明天去余姚玩了 去放松下心情 回来在写 最小生成树之prim算法
上面任何有关算法内容 如果你和我一样是初学者 还是去看大牛博客 比较好.......
今天我们先来讲下Kruskal算法(它不能处理权重为负的情况)
1.首先 这个算法第一步是要将图中所有的边进行排序 这个过程我们可以直接调用sort完成 不仅因为它方便 而且效率也不低
2.因为我们所要的生成树是权重最小的 所以排序是从小到大的 我们依次取出每条边(u,v)
3.这边的关键是加进边的时候 判断它的连通性:这里我们运用很强大的Union-Find-Set(并查集)
并查集 我这边并不想展开去谈 而且对于这个算法 我只是用到了它的最基础的路径压缩的查询函数
累了 刚和小伙伴们玩了好久 导致这个页面静止很久了…… 接下来 我就直接给出Kruskal的渣渣模板(你有任何疑问 去访问大牛的博客)--我这边纯粹是个人的回顾和输给同学的赌
int cmp(const int i , cosnt int j)
{
return value[i]<value[j];//value数组是指边的权重
}//这里运用了间接排序
int find(int x)
{
return x==father[x]?x:father[x]=find( father[x] );
}//含路径压缩的 递归式并查集
void inital(int n,int m)
{
for(int i=0;i<n;i++)
father[i]=i;//初始化并查集
for(int i=0;i<m;i++)
side[i]=i;//初始化边的序号
}
int Kruskal()
{
int sum=0;
sort(r,r+m,cmp)
for(int i=0;i<m;i++)
{
int temp=r[i];
int x=find(begin[temp]);//begin是一条边的一个端点
int y=find(end[temp]);//end是一条边的一个端点
if(x!=y)
{
sum+=value[x]//这条边加入MST之中(MST-最小生成树的边的集合)
father[x]=y;//将X合并到Y节点下面
}
}
return sum;//这样就求出解了
}
该死的 排位连赢2盘 之后连输2盘 心情都没了 糟糕透了。。。。
明天去余姚玩了 去放松下心情 回来在写 最小生成树之prim算法
上面任何有关算法内容 如果你和我一样是初学者 还是去看大牛博客 比较好.......