Untitled
unknown
java
2 years ago
4.4 kB
0
Indexable
Never
package sol6; import java.io.File; import java.io.FileNotFoundException; import java.util.*; public class solution6 { static ArrayList<Edge> edgeList; static ArrayList<ArrayList<Edge>> Gf; static int N,M,C,P; static int[] removeEdges; public static class Edge{ public int from, to, RESCAP; public final int CAPACITY; public Edge residual; public boolean ACTIVATED; public Edge(int from, int to, int cap) { this.from = from; this.to = to; this.CAPACITY = cap; this.RESCAP = cap; this.ACTIVATED = true; } public int getRC() { return ACTIVATED ? RESCAP : 0; } } public static void main(String[] args) throws FileNotFoundException { formatter(); int nbrOfNodes = 0; int p; for(int i = 0; i < removeEdges.length; i++) { //Deactivate all edges in removeEdges. Can be all edges. p = removeEdges[i]; edgeList.get(p).ACTIVATED = false; edgeList.get(p).residual.ACTIVATED = false; } int flow = Ford_Fulkerson(0, N-1, Gf); //Perform first Ford Fulkerson method Edge m; for(int i = removeEdges.length-1; i >= 0 && flow < C; i--) { //So least-activated graph is alredy in place m = edgeList.get(removeEdges[i]); // and we just Activate from the end of removeEdges-list. m.ACTIVATED = true; // KEY INSIGHT: Activating another edge can only increase or add nothing to the flow. m.residual.ACTIVATED = true; // CONVERSELY: Deactivatning another edge may only decrease or add nothing to the flow flow += Ford_Fulkerson(0, N-1, Gf); nbrOfNodes += 1; //This is dependent on the order of P in reverse order. } System.out.println(removeEdges.length - nbrOfNodes + " " + flow); } public static void formatter() throws FileNotFoundException { //File input = new File("C:/Users/Carl/Programmering/EDAF05-labs-public/6railwayplanning/data/secret/4huge.in"); Scanner scan = new Scanner(System.in); String[] first = scan.nextLine().split(" "); N = Integer.parseInt(first[0]); M = Integer.parseInt(first[1]); C = Integer.parseInt(first[2]); P = Integer.parseInt(first[3]); int from, to, cap; edgeList = new ArrayList<>(); Gf = new ArrayList<>(); for(int i =0; i < N; i++){Gf.add(new ArrayList<Edge>());} for (int i = 0; i < M; i++) { String[] line = scan.nextLine().split(" "); from = Integer.parseInt(line[0]); to = Integer.parseInt(line[1]); cap = Integer.parseInt(line[2]); Edge m1 = new Edge(from, to, cap); Edge m2 = new Edge(to, from, cap); m1.residual = m2; m2.residual = m1; edgeList.add(m1); Gf.get(from).add(m1); Gf.get(to).add(m2); } removeEdges = new int[P]; for (int i =0; i < P; i++){removeEdges[i] = Integer.parseInt(scan.nextLine());} } public static HashMap<Integer, Edge> BFS(int s, int t, ArrayList<ArrayList<Edge>> graph){ //BFS according to course literature... int V = graph.size(); int v,w; boolean[] visited = new boolean[V]; LinkedList<Integer> q = new LinkedList<>(); visited[s] = true; HashMap<Integer, Edge> pred = new HashMap<>(); q.add(s); while(q.size() != 0) { v = q.poll(); for (Edge m : graph.get(v)) { w = m.to; if(visited[w] == false && m.getRC() > 0) { //i.e to is not visited and the edge is activated if (w == t) { pred.put(w, m); return pred; } q.add(w); pred.put(w,m); visited[w] = true; } } } return new HashMap<Integer, Edge>(); //If no path was found then return empty HashMap } public static int augment(int t, HashMap<Integer, Edge> pred) { int flow = Integer.MAX_VALUE; int w = t; Edge m; while(!Objects.isNull(pred.get(w))) { //Hitta delta m = pred.get(w); flow = Math.min(flow, m.getRC()); w = m.from; } w = t; while(!Objects.isNull(pred.get(w))) { // Updatera pred och rescap m = pred.get(w); m.RESCAP -= flow; // = c_e - f_e , forward edge m.residual.RESCAP += flow; // = f_e , backward edge w = m.from; // traverse backwards } return flow; } public static int Ford_Fulkerson(int s, int t, ArrayList<ArrayList<Edge>> Gf) { //*Edmond-Karp's //temp = BFS(s,t, Gf); HashMap<Integer, Edge> pred = BFS(s,t,Gf); //Find path with bfs int currentMaximum = 0; while(!pred.isEmpty()) { currentMaximum += augment(t, pred); pred = BFS(s,t,Gf); } return currentMaximum; } }