最短路徑條數問題


問題描述:

給定如圖所示的無向連通圖,假定圖中所有邊的權值都為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];
  •  用隊列保存目前遍歷的節點。

 

 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];
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM