问题描述:
给定如图所示的无向连通图,假定图中所有边的权值都为1,显然,从源点A到终点T的虽短路径有多条,求不同的最短路径的数目。

权值相同的最短路径问题,则但愿点Dijkstra算法退化成广度优先搜索,假定起点为0,终点为N。
用动态规划的思想:
- 使用两个辅助数组:
- 步数:step[0...N],记录从起点到某个顶点i的走的最小步数;
- 路径条数:path[0...N],记录从起点到某个顶点的最短路径的条数;
- 总体思路是:根据步数更新最短路径的条数。
- 考虑:当从当前顶点i扩散到其某相邻顶点j时:
- 如果step[j] == 0,说明之前还没有路径到达过顶点j;活着step[j] > step[i] + 1,则说明之前有顶点走过这条边,且步数还要比目前走的路径长,因此可以用当前路径i的信息更新j.
- 则step[j] = step[i] + 1;
- path[j] = path[i];
- 如果step[j] == step[i] + 1,说明之前有顶点走过这条边,并且步数跟从i到j的步数一样,都是最短路径,因此更新j.
- step[j] 不变;
- path[j] = path[j] + path[i];
- 如果step[j] == 0,说明之前还没有路径到达过顶点j;活着step[j] > step[i] + 1,则说明之前有顶点走过这条边,且步数还要比目前走的路径长,因此可以用当前路径i的信息更新j.
- 用队列保存目前遍历的节点。
Code:
class NumOfShortestPath {
private int[][] aja = {
/*0*/{0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
/*1*/{1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0},
/*2*/{0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0},
/*3*/{0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0},
/*4*/{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
/*5*/{0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0},
/*6*/{0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0},
/*7*/{0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0},
/*8*/{0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0},
/*9*/{0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0},
/*10*/{0,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0},
/*11*/{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1},
/*12*/{0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0},
/*13*/{0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0},
/*14*/{0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1},
/*15*/{0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0},
};
public int[][] getData() {
return aja;
}
public int getNumOfShortestPahtes(int[][] edge) {
int len = edge.length;
int[] step = new int[len];
int[] path = new int[len];
path[0] = 1;
Queue<Integer> q = new LinkedList<Integer>();
q.add(0); //将起点放入
while(!q.isEmpty()) {
int element = q.remove();
for(int j=1; j<len; j++) {
if(edge[element][j] == 1) {
if(step[j] == 0 || step[j] > step[element] + 1) {
step[j] = step[element] + 1;
path[j] = path[element];
q.add(j);
}
else if(step[j] == step[element] + 1)
path[j] += path[element];
}
}
}
return path[len-1];
}
}
来源:https://www.cnblogs.com/little-YTMM/p/5448652.html