- 1、本文档共50页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
[数学]图论算法
图论算法 最小生成树 Prim Kruskal 最短路径 Bellman-Ford Dijkstra Floyd-Warshall 有向图的强连通分量 二部图 网络流 图的数据结构 图G=(V, E) 点集V 边集E,边(u, v) 权集W,边(u,v)有权w 邻接矩阵表示 邻接表表示 图的遍历 DFS或BFS 图的数据结构 邻接矩阵 邻接表 最小生成树(Minimum Spanning Tree) G(V,E)是无向连通赋权图,G’(V’,E’)是包含G中所有顶点的树,且树中各边权总和最小,则G’是最小生成树(可能不唯一) 容易想到用贪心策略。 Prim Kruskal 构造下图的最小生成树 Prim思想: 1.从V中任取一结点放入V; 2.在所有的端点分别在(V-V)和V中的边中,选一条权最小的加入E; 3.将边E‘在(V-V’)中的顶点从V中取出放入V; 4.重复步骤2~3,直到V与V相等为止。 //该算法步步为营,每步生成的结果均为最终结果的一部分。它每次从连接V’与(V-V’)的边中选最小边,所选出的不一定是所有尚未选出的属于最小生成树的边中的最小者。 时间复杂度:O(ElgV) Prim 算法数据结构 Prim程序基本结构: void Prim() { int i,j,k,min,lowcost[vex],closest[vex]; for(i=2;i=n;i++) { lowcost[i]=c[1][i];//第1个点到其他点的代价 closest[i]=1;//初始时,所有点的起点都是点1 } for(i=2;i=n;i++) { min=maxcost; //maxcost一个很大的数 for(j=2;j=n;j++) if(closest[j]lowcost[j]minlowcost[j]0) { min=lowcost[j];//在v中找到最小的代价点k k=j; } closest[k]=0;//k归入u中 for(j=2;j=n;j++) if(closest[j]c[k][j]lowcost[j]c[k][j]0) { lowcost[j]=c[k][j];//以k点为起点进行新一轮的代价计算,更 // 新lowcost[]和closest[] closest[j]=k; } } } Kruskal思想: 1.将边按权值由小到大排序。 2.每次加最小边 不构成回路。 3.加进了n-1条边就得到了最小生成树 //Kruskal算法并不保证每步生成的结果是连通的(中间结果可能不是树)。 Kruskal程序基本结构: 优先队列+并查集 用优先队列取最小边 用并查集找是否构成回路 Kruscal 示例: 最短路径 (Shortest Path): 最短路径问题:如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小。 边上权值非负情形的单源最短路径问题 — Dijkstra算法 边上权值为任意值的单源最短路径问题 — Bellman-Ford算法 所有顶点之间的最短路径 — Floyd算法 Dijkstra思想: 初始化: S ← { v0 };dist[j] ← Edge[0][j], j = 1, 2, …, n-1; 1、求出最短路径的长度: dist[k] ← min{ dist[i] }, i ? V- S ; S ← S U { k }; 2、 修改: dist[i] ←min{ dist[i], dist[k] + Edge[k][i] }, for i?V- S ; 3、 判断: 若S = V, 则算法结束,否则转1。 引入一个辅助数组dist。dist[i]表示当前从源点v0到终点vi 的最短路径的长度。时间复杂度:O(V2) Dijkstra程序基本结构: void dijkstra(int v)//原点是v { for(i=1;i=n;i++){ dist[i] = c[v][i]; s[i] = 0; // i不在集合S中 if(dist[i]
文档评论(0)