zoukankan      html  css  js  c++  java
  • 矩阵从左上到右下的最短距离问题

    1、问题:只允许向下或者向右,求从左上到右下的最短距离,动态规划法

    1 6 3 1 1 1
    6 0 2 5 1 1
    3 2 0 3 4 1
    1 5 3 0 2 3
    6 7 4 7 5 2
    2 6 1 3 4 9
     1 public int minPathSum(int[][] grid) {
     2     if(grid==null || grid.length==0) return 0;
     3     int m = grid.length;
     4     int n = grid[0].length;
     5     int[][] p = new int[m][n];
     6     for (int i = 0; i < m; i++) {
     7         for (int j = 0; j < n; j++) {
     8             if (i == 0 && j == 0)
     9                 p[i][j] = grid[i][j];
    10             else if (i == 0 && j > 0)
    11                 p[i][j] = p[i][j-1] + grid[i][j];
    12             else if (i > 0 && j == 0)
    13                 p[i][j] = p[i-1][j] + grid[i][j];
    14             else
    15                 p[i][j] = Math.min(p[i-1][j], p[i][j-1]) + grid[i][j];
    16         }
    17     }
    18     return p[m-1][n-1];
    19 }

    2、问题:允许上下左右走,求从左上到右下的最短距离

    1 6 3 1 1 1
    6 0 2 5 1 1
    3 2 0 3 4 1
    1 5 3 0 2 3
    6 7 4 7 5 2
    2 6 1 3 4 9

    每个方格看成是一个点,可以构造N*M+2(源点和目标点)个点的图,然后用最短路径算法求解

    法1:下面是dijkstra算法

     1 public void dijkstra(int[][] graph, int source){
     2     int n = graph.length;
     3     int[] dis = new int[n];
     4     boolean[] set = new boolean[n];
     5     // 初始化
     6     for(int i=0; i<n; i++){
     7         // -1表示不可达
     8         dis[i] = graph[source][i];
     9     }
    10     dis[source] = 0;
    11     set[source] = true;
    12 
    13     for(int i=0; i<n-1; i++){
    14         // 找到V中距离源点最近的点
    15         int mindis = Integer.MAX_VALUE;
    16         int minIndex=0;
    17         for(int v=0; v<n; v++){
    18             if(!set[v] && dis[v]<mindis && dis[v]!=-1){
    19                 mindis = dis[v];
    20                 minIndex = v;
    21             }
    22         }
    23 
    24         // 更新源点到V中每个点的距离
    25         set[minIndex] = true;
    26         for(int v=0; v<n; v++){
    27             if(!set[v] && graph[minIndex][v]>0 && dis[v] > dis[minIndex]+graph[minIndex][v]){
    28                 dis[v] = dis[minIndex]+graph[minIndex][v];
    29             }
    30         }
    31     }
    32 }

    法2:用优先队列方法,广度优先搜索

    优先队列存点v和源点到v的最短路径。

    代码

      1 package hihocoder;
      2 
      3 import java.util.*;
      4 
      5 public class WaterCity2{
      6 
      7     private PriorityQueue<Point> queue = new PriorityQueue<>();
      8     private Set<Integer> visited = new HashSet<>();
      9     private int n, m;
     10     private int[] distN, distM;
     11     private Point[][] street;
     12 
     13     private class Point implements Comparable<Point>{
     14         int r;
     15         int c;
     16         int dis;
     17         boolean blocked = false;
     18         boolean visited = false;
     19 
     20         private Point(int r, int c) {
     21             this.r = r;
     22             this.c = c;
     23         }
     24 
     25         private void visitNeighbors(){
     26             if(r!=0)    update(street[r-1][c], distN[r-1]);
     27             if(r!=n-1)  update(street[r+1][c], distN[r]);
     28             if(c!=0)    update(street[r][c-1], distM[c-1]);
     29             if(c!=m-1)  update(street[r][c+1], distM[c]);
     30         }
     31 
     32         private void update(Point p, int len){
     33             if(!p.blocked && !p.visited && p.dis > dis + len){
     34                 queue.remove(p);
     35                 p.dis = dis + len;
     36                 queue.add(p);
     37             }
     38         }
     39 
     40         @Override
     41         public int compareTo(Point p){
     42             return dis-p.dis;
     43         }
     44     }
     45 
     46     private int minPath(int r0, int c0, int r1, int c1){
     47         Point start = street[r0][c0];
     48         Point end = street[r1][c1];
     49         queue.clear();
     50         visited.clear();
     51         for (int i = 0; i < n; i++) {
     52             for (int j = 0; j < m; j++) {
     53                 street[i][j].visited = false;
     54                 street[i][j].dis = Integer.MAX_VALUE;
     55             }
     56         }
     57 
     58         start.dis = 0;
     59         queue.add(start);
     60         while(!queue.isEmpty()){
     61             Point cur = queue.poll();
     62             if(cur == end) return cur.dis;
     63             cur.visited = true;
     64             cur.visitNeighbors();
     65         }
     66         return -1;
     67     }
     68 
     69     public void deal() {
     70         try(Scanner scanner = new Scanner(System.in)) {
     71             while (scanner.hasNextInt()) {
     72                 n = scanner.nextInt();
     73                 m = scanner.nextInt();
     74                 distN = new int[n-1];
     75                 distM = new int[m-1];
     76                 for (int i = 0; i < n - 1; i++) {
     77                     distN[i] = scanner.nextInt();
     78                 }
     79                 for (int i = 0; i < m - 1; i++) {
     80                     distM[i] = scanner.nextInt();
     81                 }
     82 
     83                 street = new Point[n][m];
     84                 for (int i = 0; i < n; i++) {
     85                     for (int j = 0; j < m; j++) {
     86                         street[i][j] = new Point(i, j);
     87                     }
     88                 }
     89 
     90                 int k = scanner.nextInt();
     91                 for (int i = 0; i < k; i++) {
     92                     street[scanner.nextInt()-1][scanner.nextInt() - 1].blocked = true;
     93                 }
     94 
     95                 int q = scanner.nextInt();
     96                 for (int i = 0; i < q; i++) {
     97                     System.out.println(minPath(scanner.nextInt()-1, scanner.nextInt()-1,
     98                             scanner.nextInt()-1, scanner.nextInt()-1));
     99                 }
    100             }
    101         }
    102     }
    103 
    104     public static void main(String[] args){
    105         new WaterCity2().deal();
    106     }
    107 }
  • 相关阅读:
    UEFI和GPT
    EFI/UEFI BIOS 入门
    UEFI+GPT模式下的Windows系统中分区结构和默认分区大小及硬盘整数分区研究
    UEFI和Legacy及UEFI+Legacy启动的区别
    UEFI与MBR区别
    UI基础字典转模型
    UI基础九宫格
    UI基础UIView常见属性及方法
    UI基础控件UIButton
    OC中NSFileManager类 和 copy一些用法
  • 原文地址:https://www.cnblogs.com/shizhh/p/5728558.html
Copyright © 2011-2022 走看看