Submission details
Task:Internet connection
Sender:jeroenrobben
Submission time:2018-09-15 15:53:31 +0300
Language:Java
Status:READY
Result:
Test results
testverdicttime
#1--details
#2ACCEPTED0.24 sdetails
#3ACCEPTED0.22 sdetails
#4--details
#5--details
#6--details
#7--details
#8--details
#9--details
#10--details

Code

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.IntStream;


public class MaxFlowSolver {
	private int[][] capacities;
	private int[][] labels;
	private int[][] flowAmounts;
	private boolean[] isNodeCheckedArray;
	
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        MaxFlowSolver solver = new MaxFlowSolver(parseInputToCapacities(scan));
        System.out.println(solver.calculateMaxFlow());
        scan.close();
    }
    
    public static int[][] parseInputToCapacities(Scanner scanner) {
    	int amountNodes = scanner.nextInt();
    	int amountConnectionsNotProcessed = scanner.nextInt();
    	int[][] capacities = new int[amountNodes][amountNodes];
    	
    	while(amountConnectionsNotProcessed > 0) {
    		capacities[scanner.nextInt()-1][scanner.nextInt()-1] = scanner.nextInt();
    		amountConnectionsNotProcessed--;
    	}
    	return capacities;
    }
    
    public MaxFlowSolver(int[][] capacities) {
    	this.capacities = capacities;
    	this.flowAmounts = new int[getAmountNodes()][getAmountNodes()];
    	this.isNodeCheckedArray = new boolean[getAmountNodes()];
    }
    
    public int[] getLabelAtNode(int node) {
    	return labels[node];
    }
    
    public boolean isNodeLabeled(int node) {
    	return labels[node][1] > -1;
    }
    
    public boolean isEndNodeLabeled() {
    	return isNodeLabeled(getAmountNodes() -1);
    }
    
    public boolean isNodeChecked(int node) {
    	return isNodeCheckedArray[node];
    }
    
    public void setNodeChecked(int node, boolean value) {
    	isNodeCheckedArray[node] = value;
    }
    
    public boolean isEdgeExistent(int sourceNode, int targetNode) {
    	return getEdgeCapacity(sourceNode, targetNode) > 0;
    }
    
    public int getEdgeCapacity(int sourceNode, int targetNode) {
    	return capacities[sourceNode][targetNode];
    }
    
    public int getEdgeFlow(int sourceNode, int targetNode) {
    	return flowAmounts[sourceNode][targetNode];
    }
    
    public int getCurrentFlow() {
    	return IntStream.of(flowAmounts[0]).sum();
    }
    
    public int getAmountNodes() {
    	return this.capacities.length;
    }
    
    public void setLabel(int node, int deltaNode, int delta) {
    	labels[node][0] = deltaNode;
    	labels[node][1] = delta;
    }
    
    public boolean isGoodEdge(int sourceNode, int targetNode) {
    	return getEdgeCapacity(sourceNode, targetNode) > 0;
    }
    
    
    public void clearLabels() {
    	this.labels = new int[getAmountNodes()][2];
    	for(int[] nodeLabel: labels) {
    		nodeLabel[0] = -1;
    		nodeLabel[1] = -1;
    	}
    	this.labels[0][1] = Integer.MAX_VALUE;
    }
    
    public void clearNodesChecked() {
    	Arrays.fill(isNodeCheckedArray, false);
    }
    
    public int calculateMaxFlow() {
    	clearLabels();
    	clearNodesChecked();
    	
    	while(!isEndNodeLabeled()) {
    		int nextNodeToCheck = getNextUncheckedNodeWithLabel();    		
        	if(nextNodeToCheck == -1) { //Done
        		return getCurrentFlow();
        	}
        	else {
        		setNodeChecked(nextNodeToCheck, true);
        		labelNeighbourNodes(nextNodeToCheck);
        	}        	
    	}
    	upgradeFlow();
		return calculateMaxFlow();
    	
    }
    
    public int getNextUncheckedNodeWithLabel() {
//    	for(int node = 0; node < getAmountNodes(); node++) {
//    		if(!isNodeChecked(node) && isNodeLabeled(node)) {
//    			return node;
//    		}
//    	}
    	for(int node = getAmountNodes()-1; node >= 0; node--) {
    		if(!isNodeChecked(node) && isNodeLabeled(node)) {
    			return node;
    		}
    	}
    	return -1;
    }
    
    public void labelNeighbourNodes(int node) { // TODO
    	int delta = getLabelAtNode(node)[1];
    	int nextNeighbourToCheck = 0;
    	while (nextNeighbourToCheck < getAmountNodes()) {
    		if(nextNeighbourToCheck != node) {
    			if(isEdgeExistent(node, nextNeighbourToCheck)) {
    				int flow = getEdgeFlow(node, nextNeighbourToCheck);
    				int capacity = getEdgeCapacity(node, nextNeighbourToCheck);
    				int diffFlowCapacity = capacity - flow;
    				if(diffFlowCapacity > 0) {
    					setLabel(nextNeighbourToCheck, node, Math.min(delta, diffFlowCapacity));
    				}
    				
    			}
    			if(isEdgeExistent(nextNeighbourToCheck, node)) {
    				int flow = getEdgeFlow(nextNeighbourToCheck, node);
    				if(flow > 0) {
    					setLabel(nextNeighbourToCheck, node, Math.min(delta, flow));
    				}
    			}
    		}
    		nextNeighbourToCheck++;
    	}
    }
    
    public void upgradeFlow() { //TODO
    	int currentNode = getAmountNodes() - 1;
    	int nextNode = getLabelAtNode(currentNode)[0];
    	int delta = getLabelAtNode(getAmountNodes() - 1)[1];
    	
    	while(currentNode > 0) {
    		if(isGoodEdge(nextNode, currentNode)) {
    			flowAmounts[nextNode][currentNode] += delta;
    		}
    		else {
    			flowAmounts[nextNode][currentNode] -= delta;
    		}
    		currentNode = nextNode;
    		nextNode = getLabelAtNode(currentNode)[0];
    	}
    }
    
   
    
}

Test details

Test 1

Verdict:

input
10 20
5 6 19
4 5 47
3 5 7
4 9 62
...

correct output
73

user output
(empty)

Test 2

Verdict: ACCEPTED

input
10 20
2 4 63
7 9 54
6 7 16
2 3 9
...

correct output
110

user output
110

Test 3

Verdict: ACCEPTED

input
10 20
5 6 90
2 3 46
7 8 80
6 7 60
...

correct output
29

user output
29

Test 4

Verdict:

input
10 20
3 4 76
5 7 8
3 8 71
4 7 24
...

correct output
95

user output
(empty)

Test 5

Verdict:

input
10 20
1 8 22
6 7 40
4 5 20
8 10 77
...

correct output
156

user output
(empty)

Test 6

Verdict:

input
100 1000
63 85 864540192
22 91 974117435
64 66 953124912
85 88 6080960
...

correct output
4397669179

user output
(empty)

Test 7

Verdict:

input
100 1000
36 93 760720873
12 75 175717522
78 79 340128710
80 83 181753465
...

correct output
5298558023

user output
(empty)

Test 8

Verdict:

input
100 1000
20 60 909693891
55 91 570199535
21 41 118646902
37 82 824735480
...

correct output
5466229311

user output
(empty)

Test 9

Verdict:

input
100 1000
26 44 753330451
62 67 821574279
70 95 219303983
7 44 980013084
...

correct output
4893925638

user output
(empty)

Test 10

Verdict:

input
100 1000
15 89 501388091
50 71 396801720
15 92 324349822
29 85 184420157
...

correct output
6956499595

user output
(empty)