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 = '\0';
 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 }

 

posted on 2015-04-03 22:52  DevinZ  阅读(444)  评论(0编辑  收藏  举报

导航