Coursera algorithm II PA4

题意:

所给数据中是否有负环? 没有负环的图中所有路径中最短的值

思路:

1. bellmanford 判断负环

2. flodyWarshall 求所有定点的最短路径

细节:

1. bellmanford 算法时间复杂度为 o(n^3), 因为图的使用邻接矩阵存储的,  使用邻接表代码会容易理解些, 引用
wiki 的伪代码





1
2
3
4
5
6
// 步骤2:重复对每一条边进行松弛操作
for i from 1 to size(vertices)-1:
for each edge (u, v) with weight w in edges:
if distance[u] + w < lt; distance[v]:
distance[v] := distance[u] + w
predecessor[v] := u

每次收缩至少能够使一个点达到其最小距离, 最差的情况就是 1 -> 2 ->…n, 需要 n-1 次才能收缩完毕
2. 负环判断.
bellmanford 算法运行完毕后, 所得的结果应当是最终解, 除非有负环. 因此, 运行完 bellmanford 算法后, 再进行一次对所有收缩,若
dist 的值发生了变化(变小), 则说明出现了负环.
3. flodyWarshall算法:

设D_{i,j,k}为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。
若最短路径经过点k,则D_{i,j,k}=D_{i,k,k-1}+D_{k,j,k-1};
若最短路径不经过点k,则D_{i,j,k}=D_{i,j,k-1}。
因此,D_{i,j,k}=\mbox{min}(D_{i,k,k-1}+D_{k,j,k-1},D_{i,j,k-1})。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维

4. 动态规划算法第一件事就是要把最外层的循环变量确定, 确定的方式就是看状态转移方程的变化变量
5. 空间降维的方法.
先不考虑降维不降维的问题, 用笔画图模拟出矩阵或数组中的某一个值是由哪些导出的(在我后来做题中, 发现有新值是由通过request旧值更新,
如floydwarshell, 而也有一些dp的题目, 新值是通过旧值push更新的, 比如 poj 棋盘问题).
根据值的导出顺序来判断如何设置循环变量的遍历顺序(从大到小或从小到大)以使用滚动数组或滚动矩阵
6. 数学之美有一个小节讲到 google map
寻找城市之间的最短路径, 使用的就是 floydwarshell 算法

Submit original work, copying violates the
class Honor Code




int bellmanford(int path[], int dist[], int verNum, int edge[][maxVertex], int src) {
// init array path and dist
for(int i = 0; i < lt; verNum; i ++) {
path[i] = src;
dist[i] = edge[src][i];
}
 
for(int i = 1; i &lt; verNum; i ++) {
// 收缩
for(int j = 0; j &lt; verNum; j++) {
if(j == src) continue;
for(int k = 0; k &lt; verNum; k ++) {
if(edge[k][j] &lt; inf &amp;&amp; dist[k] &lt; inf &amp;&amp; dist[k] + edge[k][j] &lt; dist[j]) {
path[j] = k;
dist[j] = edge[k][j] + dist[k];
}
}
}
}
for(int i = 0; i &lt; verNum ; i++) {
cout &lt;&lt; dist[i] &lt;&lt; " ";
}
cout &lt;&lt; endl;
dist[src] = 0;
// check if exists a negative cycle
for(int i = 0; i &lt; verNum; i++) {
for(int j = 0; j &lt; verNum; j ++) {
if(edge[j][i] &lt; inf &amp;&amp; dist[j] &lt; inf &amp;&amp; dist[j] + edge[j][i] &lt; dist[i])
return 0;
}
}
return 1;
}




int flodyWarshall(int dist[][maxSize], int path[][maxSize], int edge[][maxSize], int verNum) {
for(int i = 0; i &lt; verNum; i++) {
for(int j = 0; j &lt; verNum; j ++) {
if(i == j) {
dist[i][j] = 0;
}else {
dist[i][j] = edge[i][j];
}
}
}
for(int k = 0; k &lt; verNum; k ++) {
for(int i = 0; i &lt; verNum; i ++) {
for(int j = 0; j &lt; verNum; j++) { if(dist[i][j] &gt; dist[i][k]+dist[k][j]) {
dist[i][j] =dist[i][k]+dist[k][j];
path[i][j] = k;
}
}
}
}
int minDist = 9999999;
for(int i = 0; i &lt; verNum; i ++) {
for(int j = 0; j &lt; verNum; j ++) {
if(dist[i][j] &lt; minDist)
minDist = dist[i][j];
}
}
return minDist;
}


Coursera algorithm II PA4,布布扣,bubuko.com

时间: 2024-10-10 23:45:42

Coursera algorithm II PA4的相关文章

Coursera Algorithm II PA2 Q2

题意: what is the largest value of k such that there is a k-clustering with spacing at least 3?  That is, how many clusters are needed to ensure that no pair of nodes with all but 2 bits in common get split into different clusters? 即, 海明距离小于等于 2 的所有点要被

Coursera Algorithm Part II PA2

题意: computing a max-spacing k-clustering. spacing 是指两个 cluster 之间的最小距离 输入: [number_of_nodes][edge 1 node 1] [edge 1 node 2] [edge 1 cost][edge 2 node 1] [edge 2 node 2] [edge 2 cost] 输出: maximum spacing of a 4-clustering. 将所有的点分到4个非空的 cluster 中, 如何分才

Huffman Algorithm (ii) 计算字符权重

/* *========================================================== * Filename : cw.cpp * Description : * * Author : RollStone (rs), [email protected] * Created : 10/11/2014 11:02 * Version : 1.0 * Last_Change : 2014-10-11 11:37:33 * Copyright : All Right

quora 的东西就是不一样

Coding is just a part of process of problem solving, You should need to understand the underlying problem and efficient solution within given constraint. So i will better tell you,how to be better at problem solving: Programming Language & Computer s

[Stanford Algorithms: Design and Analysis, Part 2]

Specific topics in Part 2 include: greedy algorithms (scheduling, minimum spanning trees, clustering, Huffman codes), dynamic programming (knapsack, sequence alignment, optimal search trees, shortest paths), NP-completeness and what it means for the

[Algorithm] Reverse String II

给定一个字符串,要求把字符串前面的若干字符移动到字符串尾部. 解法一:蛮力法 首先想考虑将一个字符移到尾部的方法.代码如下: void LeftShiftOne(char* s, int n) { char t = s[0]; for (int i = 1; i != n; i++) s[i - 1] = s[i]; s[n - 1] = t; } 如果要移动m个字符串,则依次对函数LeftShiftOne执行m次即可.代码如下: void LeftRotateString(char* s, i

[LeetCode] 349 Intersection of Two Arrays &amp; 350 Intersection of Two Arrays II

这两道题都是求两个数组之间的重复元素,因此把它们放在一起. 原题地址: 349 Intersection of Two Arrays :https://leetcode.com/problems/intersection-of-two-arrays/description/ 350 Intersection of Two Arrays II:https://leetcode.com/problems/intersection-of-two-arrays-ii/description/ 题目&解法

Intersection of Two Arrays I &amp; II

题目链接:https://leetcode.com/problems/intersection-of-two-arrays/ 题目大意:要求两个数组的交集(注意集合是不能含有重复的元素的) 方法1) 先对两个数组进行排序,设置两个指针pA和pB,分别指向这两个数组,比较nums1[pA]和nums[pB] a. 如果想等,则为交集中的元素,++pA, ++pB b. 如果nums[pA] < nums[pB],则++pA c. 否则,++pB 注意数组中有重复的元素(实现代码中的小trick)

1245 - Harmonic Number (II)(规律题)

1245 - Harmonic Number (II)   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 MB I was trying to solve problem '1234 - Harmonic Number', I wrote the following code long long H( int n ) {     long long res = 0;     for( int i =