Submission #1148121

#TimeUsernameProblemLanguageResultExecution timeMemory
1148121rebe__1Coin Collecting (JOI19_ho_t4)Java
37 / 100
1103 ms232612 KiB
import java.util.*; public class joi2019_ho_t4 { static class Edge { int to, rev, cap, cost; public Edge(int to, int rev, int cap, int cost) { this.to = to; this.rev = rev; this.cap = cap; this.cost = cost; } } static final int INF = Integer.MAX_VALUE / 2; static class MinCostFlow { int N; ArrayList<Edge>[] graph; int[] dist, potential, prevV, prevE; @SuppressWarnings("unchecked") public MinCostFlow(int N) { this.N = N; graph = new ArrayList[N]; for (int i = 0; i < N; i++) { graph[i] = new ArrayList<>(); } dist = new int[N]; potential = new int[N]; prevV = new int[N]; prevE = new int[N]; } public void addEdge(int s, int t, int cap, int cost) { graph[s].add(new Edge(t, graph[t].size(), cap, cost)); graph[t].add(new Edge(s, graph[s].size() - 1, 0, -cost)); } public int minCostFlow(int s, int t, int f) { int res = 0; Arrays.fill(potential, 0); while (f > 0) { PriorityQueue<Pair> pq = new PriorityQueue<>(); Arrays.fill(dist, INF); dist[s] = 0; pq.add(new Pair(s, 0)); while (!pq.isEmpty()) { Pair p = pq.poll(); int v = p.v; if (dist[v] < p.dist) continue; for (int i = 0; i < graph[v].size(); i++) { Edge e = graph[v].get(i); if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + potential[v] - potential[e.to]) { dist[e.to] = dist[v] + e.cost + potential[v] - potential[e.to]; prevV[e.to] = v; prevE[e.to] = i; pq.add(new Pair(e.to, dist[e.to])); } } } if (dist[t] == INF) { return -1; } for (int v = 0; v < N; v++) { if (dist[v] < INF) potential[v] += dist[v]; } int addFlow = f; for (int v = t; v != s; v = prevV[v]) { addFlow = Math.min(addFlow, graph[prevV[v]].get(prevE[v]).cap); } f -= addFlow; res += addFlow * potential[t]; for (int v = t; v != s; v = prevV[v]) { Edge e = graph[prevV[v]].get(prevE[v]); e.cap -= addFlow; graph[v].get(e.rev).cap += addFlow; } } return res; } } static class Pair implements Comparable<Pair> { int v, dist; public Pair(int v, int dist) { this.v = v; this.dist = dist; } public int compareTo(Pair other) { return Integer.compare(this.dist, other.dist); } } private static int constrain(int value, int min, int max) { return Math.max(min, Math.min(max, value)); } private static long calculateMovesToBoundary(int col, int row, int numColumns) { long moves = 0; if (row < 1) moves += (1 - row); if (row > 2) moves += (row - 2); if (col < 1) moves += (1 - col); if (col > numColumns) moves += (col - numColumns); return moves; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int numColumns = sc.nextInt(); int totalCoins = 2 * numColumns; int[][] grid = new int[3][numColumns + 1]; long boundaryCost = 0; for (int i = 0; i < totalCoins; i++) { int col = sc.nextInt(); int row = sc.nextInt(); boundaryCost += calculateMovesToBoundary(col, row, numColumns); int validCol = constrain(col, 1, numColumns); int validRow = constrain(row, 1, 2); grid[validRow][validCol]++; } int nodes = 2 * numColumns; int[] supply = new int[nodes]; for (int c = 1; c <= numColumns; c++) { for (int r = 1; r <= 2; r++) { int idx = (c - 1) * 2 + (r - 1); supply[idx] = grid[r][c] - 1; } } int s = nodes; int t = nodes + 1; int totalNodes = nodes + 2; MinCostFlow mcf = new MinCostFlow(totalNodes); for (int c = 1; c < numColumns; c++) { for (int r = 1; r <= 2; r++) { int u = (c - 1) * 2 + (r - 1); int v = (c) * 2 + (r - 1); mcf.addEdge(u, v, INF, 1); mcf.addEdge(v, u, INF, 1); } } for (int c = 1; c <= numColumns; c++) { int u = (c - 1) * 2 + 0; int v = (c - 1) * 2 + 1; mcf.addEdge(u, v, INF, 1); mcf.addEdge(v, u, INF, 1); } int totalPositive = 0; for (int i = 0; i < nodes; i++) { if (supply[i] > 0) { mcf.addEdge(s, i, supply[i], 0); totalPositive += supply[i]; } else if (supply[i] < 0) { mcf.addEdge(i, t, -supply[i], 0); } } int flowCost = mcf.minCostFlow(s, t, totalPositive); long answer = boundaryCost + flowCost; System.out.println(answer); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...