zoukankan      html  css  js  c++  java
  • All-Pairs Shortest Paths

    1. Disjoint Set
      Before we talk about more graph algorithms, we shall take a breath and review a basic data structure called Disjoint Set. I provide my solution to the USACO training problem "castle" here in order to evoke your memory about it:

      1 import java.io.*;
      2 import java.util.*;
      3 
      4 class DisjointSet {
      5     private int[] root;    // root of each item
      6     private int size;         // number of items
      7     
      8     public DisjointSet(int size) {
      9         if (size<=0) {
     10             throw new RuntimeException("Illegal Initial Size");
     11         } else {
     12             this.size = size;
     13             root = new int[size];
     14             for (int i=0;i<size;i++) {
     15                 root[i] = -1;
     16             }
     17         }
     18     }
     19     public int find(int idx)  {
     20         // Determine and return root[idx]
     21         if (idx<0||idx>=size) {
     22             throw new RuntimeException("IndexOutOfBounds on find");
     23         } else {
     24             int prev = root[idx];
     25             if (prev<0) {
     26                 return idx;
     27             } else {
     28                 root[idx] = find(prev);
     29                 return root[idx];
     30             }
     31         }
     32     }
     33     public void union(int i,int j) {
     34         // Merge the set of i and the set of j
     35         if (i<0||i>=size||j<0||j>=size) {
     36             throw new RuntimeException("IndexOutOfBounds on union");
     37         } else {
     38             i = find(i);
     39             j = find(j);
     40             if (i!=j) {    
     41                 // BEWARE that i and j may be identical
     42                 if (root[i]<root[j]) {
     43                     root[i] += root[j];
     44                     root[j] = i;
     45                 } else {
     46                     root[j] += root[i];
     47                     root[i] = j;
     48                 }
     49             }
     50         }
     51     }
     52     public int getSize() {
     53         return size;
     54     }
     55     public int getNum() {
     56         int val = 0;
     57         for (int i=0;i<size;i++) {
     58             if (root[i]<0) {
     59                 val++;
     60             }
     61         }
     62         return val;
     63     }
     64     public int getSetSize(int pos) {
     65         return -root[find(pos)];
     66     }
     67 }
     68 
     69 
     70 public class castle {
     71     public static BufferedReader input;
     72     public static PrintWriter output;
     73     public static DisjointSet set;
     74     public static int wid, len;
     75     public static int [][] map;
     76     
     77     public static void removeWall()  {
     78         int val=0, x=0, y=0; 
     79         char w = '';
     80         for (int j=0;j<len;j++)  {
     81             for (int i=wid-1;i>=0;i--) {
     82                 int self = set.find(i*len+j);
     83                 if (i>0) {
     84                     int north = set.find((i-1)*len+j);
     85                     if (self!=north && val<set.getSetSize(self)+set.getSetSize(north)) {
     86                         val = set.getSetSize(self)+set.getSetSize(north);
     87                         x = i+1;
     88                         y = j+1;
     89                         w = 'N';
     90                     }
     91                 }
     92                 if (j<len-1) {
     93                     int east = set.find(i*len+j+1);
     94                     if (self!=east && val<set.getSetSize(self)+set.getSetSize(east)) {
     95                         val = set.getSetSize(self)+set.getSetSize(east);
     96                         x = i+1;
     97                         y = j+1;
     98                         w = 'E';
     99                     }
    100                 }
    101             }
    102         }
    103         output.println(val);
    104         output.println(x+" "+y+" "+w);
    105     }
    106     public static void main(String[] args) throws IOException {
    107         input = new BufferedReader(new FileReader("castle.in"));
    108         StringTokenizer str = new StringTokenizer(input.readLine());
    109         len = Integer.parseInt(str.nextToken());
    110         wid = Integer.parseInt(str.nextToken());
    111         set = new DisjointSet(wid*len);
    112         map = new int[wid][len];
    113         int wall;
    114         for (int i=0;i<wid;i++)  {
    115             str = new StringTokenizer(input.readLine());
    116             for (int j=0;j<len;j++) {
    117                 wall = Integer.parseInt(str.nextToken());
    118                 map[i][j] = wall;
    119                 if ((wall&1)==0){ // West
    120                     set.union(i*len+j,i*len+j-1);
    121                 }
    122                 if ((wall&2)==0) // North
    123                     set.union(i*len+j,(i-1)*len+j);
    124             }
    125         }
    126         input.close();
    127         output = new PrintWriter(new FileWriter("castle.out"));
    128         output.println(set.getNum());
    129         int max = 0;
    130         for (int i=0;i<set.getSize();i++) {
    131             if (max<set.getSetSize(i)) {
    132                 max = set.getSetSize(i);
    133             }
    134         }
    135         output.println(max);
    136         removeWall();
    137         output.close();
    138     }
    139 }

    2. Floyd-Warshall Algorithm

      In this section, I'll use Floyd-Warshall Algorihtm to determine all-pairs shortest paths and solve the USACO training problem "cowtour":

      1 import java.io.*;
      2 import java.util.*;
      3 import java.text.*;
      4 
      5 class DisjointSet {
      6     private int[] root;    // root of each item
      7     private int size;         // number of items
      8     
      9     public DisjointSet(int size) {
     10         if (size<=0) {
     11             throw new RuntimeException("Illegal Initial Size");
     12         } else {
     13             this.size = size;
     14             root = new int[size];
     15             for (int i=0;i<size;i++) {
     16                 root[i] = -1;
     17             }
     18         }
     19     }
     20     public int find(int idx)  {
     21         // Determine and return root[idx]
     22         if (idx<0||idx>=size) {
     23             throw new RuntimeException("IndexOutOfBounds on find");
     24         } else {
     25             int prev = root[idx];
     26             if (prev<0) {
     27                 return idx;
     28             } else {
     29                 root[idx] = find(prev);
     30                 return root[idx];
     31             }
     32         }
     33     }
     34     public void union(int i,int j) {
     35         // Merge the set of i and the set of j
     36         if (i<0||i>=size||j<0||j>=size) {
     37             throw new RuntimeException("IndexOutOfBounds on union");
     38         } else {
     39             i = find(i);
     40             j = find(j);
     41             if (i!=j) {    
     42                 // BEWARE that i and j may be identical
     43                 if (root[i]<root[j]) {
     44                     root[i] += root[j];
     45                     root[j] = i;
     46                 } else {
     47                     root[j] += root[i];
     48                     root[i] = j;
     49                 }
     50             }
     51         }
     52     }
     53 }
     54 
     55 public class cowtour {
     56     public static final int INF = 1000000000;
     57     public static Scanner input;
     58     public static PrintWriter output;
     59     public static int num;
     60     public static int [][] point;
     61     public static double [][] dist;
     62     public static DisjointSet set;
     63     
     64     public static double calDist(int i,int j) {
     65         double distSq = Math.pow(point[i][0]-point[j][0],2)
     66                 + Math.pow(point[i][1]-point[j][1], 2);
     67         return Math.sqrt(distSq);
     68     }
     69     public static void shortDist() {
     70         // Floyd-Warshall Algorithm:
     71         for (int i=0;i<num;i++) {
     72             for (int j=0;j<num;j++) {
     73                 for (int k=0;k<num;k++) {
     74                     if (dist[k][j]>dist[k][i]+dist[i][j]) {
     75                         dist[k][j]=dist[j][k]=dist[k][i]+dist[i][j];
     76                     }
     77                 }
     78             }
     79         }
     80     }
     81     public static double calAllDiameter(double [] d) {
     82         double val = 0;
     83         for (int i=0;i<num;i++) {
     84             d[i] = 0;
     85             for (int j=0;j<num;j++) {
     86                 if (set.find(i)==set.find(j) && dist[i][j]>d[i]) {
     87                     d[i] = dist[i][j];
     88                 }
     89             }
     90             if (d[i]>val) {
     91                 val = d[i];
     92             }
     93         }
     94         return val;
     95     }
     96     public static void solve() {
     97         shortDist();
     98         double [] d = new double[num];
     99         double limit = calAllDiameter(d);
    100         double val = INF;
    101         for (int i=0;i<num;i++) {
    102             for (int j=0;j<i;j++) {
    103                 if (set.find(i)!=set.find(j)) {
    104                     double max = d[i]+calDist(i,j)+d[j];
    105                     if (limit>max) {
    106                         max = limit;
    107                     }
    108                     if (val>max) {
    109                         val = max;
    110                     }
    111                 }
    112             }
    113         }
    114         DecimalFormat df = new DecimalFormat(".000000");
    115         output.println(df.format(val));
    116     }
    117     public static void main(String[] args) throws IOException {
    118         input = new Scanner(new FileReader("cowtour.in"));
    119         num = input.nextInt();
    120         point = new int [num][2];
    121         dist = new double[num][num];
    122         for (int i=0;i<num;i++) {
    123             point[i][0] = input.nextInt();
    124             point[i][1] = input.nextInt();
    125         }
    126         set = new DisjointSet(num);
    127         for (int i=0;i<num;i++) {
    128             String line = input.next();
    129             for (int j=0;j<num;j++) {
    130                 if (line.charAt(j)=='1') {
    131                     dist[i][j]=dist[j][i]=calDist(i,j);
    132                     set.union(i, j);
    133                 } else {
    134                     dist[i][j]=dist[j][i]=INF;
    135                 }
    136             }
    137             dist[i][i] = 0;
    138         }
    139         input.close();
    140         output = new PrintWriter(new FileWriter("cowtour.out"));
    141         solve();
    142         output.close();
    143     }
    144 }
  • 相关阅读:
    分享 35 套精美的 PSD 图标素材
    HTML 5 标签、属性、事件及浏览器兼容性速查表
    推荐21款最佳 HTML 5 网页游戏
    二分查找
    双指针合并两个排序数组
    关于explorer.exe文件或目录已损坏的问题
    一文弄懂数组的和
    云效DevOps实践如何基于云效实现测试自动化集成和分析
    五福背后的 Web 3D 引擎 Oasis Engine 正式开源
    Delta Lake在Soul的应用实践
  • 原文地址:https://www.cnblogs.com/DevinZ/p/4411435.html
Copyright © 2011-2022 走看看