题目:股票经理人之间传消息。每个经理人只跟几个联系者之间传消息,并且时间不相同;由此求出将消息传递到所有经理人需要的最短时间?及最佳人选;
输入:
3 -----总共有几个经理人
2 2 4 3 5----与第一个经理人保持联系的有2个经理人,第一个是2号经理人,传消息时间为4;第二个是3号。消息时间为5;
2 1 2 3 6----同上;
2 1 2 2 2
5
3 4 4 2 8 5 3
1 5 8
4 1 6 4 10 2 7 5 2
0
2 2 5 1 5
0
输出:
3 2 ---通过3号经理人时间最短,需要时间2
3 10---第二个test,通过3号时间最短,需要10;
分析:用弗洛德算法计算所有节点的最短路径;
算法的主要代码:
//弗洛依德算法,顶点i到j经过k点
//用算法计算最短路径----这个地方一定是k是最外面一层!算法书上也是这么写;
//因为你是要对每个节点做更新,所以让他做最外一层更合适。。
for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i != j && f[i][j] > f[i][k] + f[k][j])
f[i][j]= f[i][k] + f[k][j];
}
}
}
算法分析:弗洛依德算法实现步骤:
- 初始化dis[][],path[][];dis中存放最短路径,path存放前一个节点;
- 计算dis[][],取1--n的所有中间节点(上面用k进行遍历),比较得到最短距离:dis[i][j] = min{dis[i][k]+d[k][j],dis[i][j]}
可以发现,弗洛依德算法的时间复杂度为O(n3),但是还挺好理解的~~
对应的另一个最短路径算法:迪杰卡斯特算法。
Dijkstra算法中,di[],path[]都只是一维的,因为其计算单点的最短距离;算法步骤:
- 初始化dis[],path[]---->用题目中给出的值进行初始化;
- 取当前dis[]中的最小值的顶点,加入到u中;dis[k] = min{dis[j] }min=dis[k];
- 由这个min更新其他节点的最小值;dis[j] = min{dis[k]+min,dis[j]}
实现代码:
private static voiddijkstra() {
for (int i = 1; i <= n; i++) {//对dis数组进行初始化,其中e[0][i]存放的是原物件的价格,没用替代物;
dis[i]= e[0][i];
}
for(int i = 1; i <= n; i++) {
intmin = Integer.MAX_VALUE;
intk = 0;
for(int j = 1; j <= n; j++) {//当前最短路径值
if(used[j] == 0 && dis[j] < min) {
k =j;
min= dis[j];
}
}
if(k == 0)
break;
used[k]= 1;
for(int j = 1; j <= n; j++) {
//更新其他节点最短路径值;
if(used[j] == 0 && e[k][j] > 0 && e[k][j] + min < dis[j]) {
dis[j]= e[k][j] + min;
}
}
}
}