Coursera 算法二 week 3 Baseball Elimination
这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import edu.princeton.cs.algs4.FlowEdge; 2 import edu.princeton.cs.algs4.FlowNetwork; 3 import edu.princeton.cs.algs4.FordFulkerson; 4 import edu.princeton.cs.algs4.ST; 5 import edu.princeton.cs.algs4.Queue; 6 import edu.princeton.cs.algs4.In; 7 import edu.princeton.cs.algs4.StdOut; 8 9 public class BaseballElimination 10 { 11 private int numberOfTeams; 12 private ST<String, Integer> st; 13 private int[] wins; 14 private int[] losses; 15 private int[] remaining; 16 private int[][] against; 17 private String[] teamName; 18 19 public BaseballElimination(String filename) 20 { 21 st = new ST<String, Integer>(); 22 In in = new In(filename); 23 numberOfTeams = in.readInt(); 24 wins = new int[numberOfTeams]; 25 losses = new int[numberOfTeams]; 26 remaining = new int[numberOfTeams]; 27 teamName = new String[numberOfTeams]; 28 against = new int[numberOfTeams][numberOfTeams]; 29 30 for (int i = 0; i < numberOfTeams; i++) 31 { 32 String name = in.readString(); 33 st.put(name, i); 34 wins[i] = in.readInt(); 35 losses[i] = in.readInt(); 36 remaining[i] = in.readInt(); 37 teamName[i] = name; 38 for (int j = 0; j < numberOfTeams; j++) 39 against[i][j] = in.readInt(); 40 } 41 } 42 43 public int numberOfTeams() 44 { 45 return numberOfTeams; 46 } 47 48 public Iterable<String> teams() 49 { 50 return st.keys(); 51 } 52 53 public int wins(String team) 54 { 55 if (!st.contains(team)) throw new IllegalArgumentException(); 56 int index = st.get(team); 57 return wins[index]; 58 } 59 60 public int losses(String team) 61 { 62 if (!st.contains(team)) throw new IllegalArgumentException(); 63 int index = st.get(team); 64 return losses[index]; 65 } 66 67 public int remaining(String team) 68 { 69 if (!st.contains(team)) throw new IllegalArgumentException(); 70 int index = st.get(team); 71 return remaining[index]; 72 } 73 74 public int against(String team1, String team2) 75 { 76 if (!st.contains(team1) || !st.contains(team2)) throw new IllegalArgumentException(); 77 int index1 = st.get(team1); 78 int index2 = st.get(team2); 79 return against[index1][index2]; 80 } 81 82 private FlowNetwork createNetwork(String team) 83 { 84 int index = st.get(team); 85 int num = numberOfTeams - 1; 86 87 int V = num + 2 + num * (num - 1) / 2; 88 int s = V - 2, t = V - 1; 89 FlowNetwork net = new FlowNetwork(V); 90 91 for (int i = 0; i < num; i++) 92 { 93 if (i < index) 94 { 95 double capacity = wins[index] + remaining[index] - wins[i]; 96 FlowEdge edge = new FlowEdge(i, t, capacity); 97 net.addEdge(edge); 98 } 99 else 100 { 101 double capacity = wins[index] + remaining[index] - wins[i + 1]; 102 FlowEdge edge = new FlowEdge(i, t, capacity); 103 net.addEdge(edge); 104 } 105 } 106 int temp = num; 107 for (int i = 0; i < num - 1; i++) 108 { 109 for (int j = i + 1; j < num; j++) 110 { 111 FlowEdge edge = new FlowEdge(temp, j, Double.POSITIVE_INFINITY); 112 net.addEdge(edge); 113 114 edge = new FlowEdge(temp, i, Double.POSITIVE_INFINITY); 115 net.addEdge(edge); 116 117 int a = i, b = j; 118 if (i >= index) a++; 119 if (j >= index) b++; 120 double capacity = against[a][b]; 121 edge = new FlowEdge(s, temp, capacity); 122 net.addEdge(edge); 123 124 temp++; 125 } 126 } 127 128 return net; 129 } 130 131 public boolean isEliminated(String team) 132 { 133 if (!st.contains(team)) throw new IllegalArgumentException(); 134 int index = st.get(team); 135 int num = numberOfTeams - 1; 136 int V = num + 2 + num * (num - 1) / 2; 137 int s = V - 2, t = V - 1; 138 139 for (int i = 0; i < num; i++) 140 { 141 int j = i; 142 if (j >= index) j++; 143 if (wins[index] + remaining[index] < wins[j]) 144 return true; 145 } 146 147 FlowNetwork net = createNetwork(team); 148 149 FordFulkerson ff = new FordFulkerson(net, s, t); 150 for (FlowEdge e : net.adj(s)) 151 if (e.capacity() != e.flow()) 152 return true; 153 154 return false; 155 } 156 157 public Iterable<String> certificateOfElimination(String team) 158 { 159 if (!st.contains(team)) throw new IllegalArgumentException(); 160 int index = st.get(team); 161 int num = numberOfTeams - 1; 162 int V = num + 2 + num * (num - 1) / 2; 163 int s = V - 2, t = V - 1; 164 Queue<String> certificate = new Queue<String>(); 165 166 boolean isEliminated = false; 167 for (int i = 0; i < num; i++) 168 { 169 int j = i; 170 if (j >= index) j++; 171 if (wins[index] + remaining[index] < wins[j]) 172 { 173 isEliminated = true; 174 certificate.enqueue(teamName[j]); 175 } 176 } 177 if (isEliminated) return certificate; 178 179 FlowNetwork net = createNetwork(team); 180 181 FordFulkerson ff = new FordFulkerson(net, s, t); 182 for (int i = 0; i < num; i++) 183 { 184 if (ff.inCut(i)) 185 { 186 int j = i; 187 if (j >= index) j++; 188 certificate.enqueue(teamName[j]); 189 isEliminated = true; 190 } 191 } 192 193 if (isEliminated) return certificate; 194 195 return null; 196 } 197 198 public static void main(String[] args) { 199 BaseballElimination division = new BaseballElimination(args[0]); 200 for (String team : division.teams()) { 201 if (division.isEliminated(team)) { 202 StdOut.print(team + " is eliminated by the subset R = { "); 203 for (String t : division.certificateOfElimination(team)) { 204 StdOut.print(t + " "); 205 } 206 StdOut.println("}"); 207 } 208 else { 209 StdOut.println(team + " is not eliminated"); 210 } 211 } 212 } 213 }