算法学习(一)-----朱流算法
来源:互联网 发布:tcp udp 端口 编辑:程序博客网 时间:2024/05/21 18:48
前言
最近的学习,深深地感受到了算法分享的重要性。
应队友的要求,写一篇简单易懂的算法讲解(希望我写的出来),深入浅出(磨磨唧唧)的讲解一下朱刘算法。
什么是朱刘算法
大家应该都知道,如何求解最小生成树,可以使用Prim, 也可以使用Kruskal, 总而言之,就是寻找使得所有节点连通的权值最小的路径。
当然,这是基于无向图而言的,而对于有向图,我们要求“最小生成树”的话,就可以使用朱刘算法。
简而言之,朱刘算法就是求有向图的最小生成树。
大概想法:
用贪心的思想每次进行选择,缩点,最终求得。
重点内容
1,选入边集——找到除root点之外,每一个点的所有入边中权值最小的,用数组in[]记录下这个最小权值,用pre[]记录到达该点的前驱;(若图中存在独立点,最小树形图是不存在的,所以在该步骤结束后,要判断一下)2,找有向环,并用数组id[]记录节点所属环的编号。3,找到环后,缩点,并更新权值。(感觉和SCC缩点差不多)4,以环数为下一次查找的点数,继续执行上述操作,直到没有环 或者 判定出不存在最小树形图为止。
建边:const int INF = 0x3f3f3f3f;const int MAXM = 40010;const int MAXN = 1010;struct Edge { int u, v, cost;//u->v,边权值为w};Edge edge[MAXM];
int pre[MAXN];//存储父节点int id[MAXN];//id【i】记录节点i所在的环的编号int visit[MAXN];//标记作用int in[MAXN];//in【i】记录i入边中最小的权值
int zhuliu(int root, int n, int m)//朱刘算法, root是起始根节点,n是最大的点,m是边数{ int res = 0;//权值 int v; while(1) { for(int i=0; i<n; i++)//遍历每一个点 in[i] = INF;//初始化in数组,将每一个入度的权值清为INF for(int i=0; i<m; i++)//遍历每一条边 { if(Edge[i].u!=Edge[i].v&&Edge[i].cost<in[Edge[i].v])//如果是一条边并且边权值小于入度的权值 { pre[Edge[i].v] = Edge[i].u;//将前一个节点记录 in[Edge[i].v] = Edge[i].cost;//更新in数组 } } for(int i=0; i<n; i++)//遍历每一个点 { if(i!=root&&in[i]==INF)//如果找到了一个入度的权值为INF,并且不是根节点 return -1;//则是没有找到最小树形图,则跳出循环 } memset(id, -1, sizeof(id));// memset(visit, -1, sizeof(visit));// int tn = 0; in[root] = 0; for(int i=0; i<n; i++)//遍历每一个节点 { res += in[i];//加入每一个点的最小入度的权值 int v = i; while(visit[v]!=i&&id[v]==-1&&v!=root)//当加入的点不在环上,不是根节点 { visit[v] = i;//标记 v = pre[v];//更新前一个节点 } if(id[v]==-1&&v!=root)//如果当前节点都已经访问过了 { for(int u=pre[v]; u!=v; u=pre[u])//找到之前的点 { id[u] = tn;//对id赋值 } id[v] = tn++;//更新此值 } } if(tn==0)//没有可以构成的树 break;//跳出 for(int i=0; i<n; i++)//当结束了while循环, { if(id[i]==-1)//如果没有找到环的标号 { id[i] = tn++;//每一个点都可以当成一个环 } } for(int i=0; i<m;)//遍历每一条边,展开环 { v = Edge[i].v;// int u = Edge[i].u; Edge[i].u = id[Edge[i].u]; Edge[i].v = id[Edge[i].v]; if(Edge[i].u!=Edge[i].v) Edge[i++].cost -= in[v]; else swap(Edge[i], Edge[--m]); } n = tn; root = id[root]; } return res;}
阅读全文
0 0
- 算法学习(一)-----朱流算法
- 算法学习(一)
- 数据压缩算法学习(一)---RLE算法
- 算法学习笔记(一)-算法基础
- 算法学习(一)----基本排序算法
- 算法学习日志(一)
- Apriori算法学习(一)
- 算法导论学习(一)
- 算法学习笔记(一)
- 算法学习--查找(一)
- 算法学习一(基础)
- 排序算法学习(一)
- 算法学习(一)分治算法
- 算法研究学习一
- 算法学习一
- 算法学习(一)
- 简单算法学习一
- 《算法导论》学习(一)
- react系列(2)表达式语法
- 做技术,有没有必要参加IT培训
- Linux(centos7)下安装OpenSSL 安装图文详解
- 【java】--sleep wait 小结
- 排序法-改良的选择排序(C)
- 算法学习(一)-----朱流算法
- S-Nim HDU
- 结构体的使用以及结构体内存对齐
- 好久不更新博客,关于spark-scala上开发的总结
- laravel手把手教学
- spark中的广播变量与累加器
- 时间序列笔记(三)
- 莫比乌斯函数求和公式理解
- 一晚上搭建个人域名博客Github+Hexo