TopCoder SRM 693 Div1 Easy: BiconnectedDiv1
解法
最小費用流そのものやんけ!!!!
コード
import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.PriorityQueue; public class BiconnectedDiv1 { public int minimize(int[] w1, int[] w2) { int V = w1.length + 1; MinimumCostFlow flow = new MinimumCostFlow(V); for (int i = 0; i < w1.length; i++) flow.addEdge(i, i + 1, 1, w1[i]); for (int i = 0; i < w2.length; i++) flow.addEdge(i, i + 2, 1, w2[i]); return flow.run(0, V - 1, 2); } class MinimumCostFlow { class Edge { int to, cap, cost, rev; Edge(int to, int cap, int cost, int rev) { this.to = to; this.cap = cap; this.cost = cost; this.rev = rev; } } private static final int INF = (int) 1e9; private ArrayList<ArrayList<Edge>> G; private int V; int[] potential; int[] dist; int[] prevV, prevE; MinimumCostFlow(int V) { this.V = V; G = new ArrayList<>(V); for (int i = 0; i < V; i++) G.add(new ArrayList<>()); potential = new int[V]; dist = new int[V]; prevE = new int[V]; prevV = new int[V]; } void addEdge(int from, int to, int cap, int cost) { G.get(from).add(new Edge(to, cap, cost, G.get(to).size())); G.get(to).add(new Edge(from, 0, -cost, G.get(from).size() - 1)); } int run(int s, int t, int flow) { int cost = 0; Arrays.fill(potential, 0); while (flow > 0) { PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() { @Override public int compare(int[] o1, int[] o2) { return Integer.compare(o1[0], o2[0]); } }); Arrays.fill(dist, INF); dist[s] = 0; queue.add(new int[]{0, s}); while (!queue.isEmpty()) { int[] p = queue.poll(); int v = p[1]; if (dist[v] < p[0]) continue; for (int i = 0; i < G.get(v).size(); i++) { Edge e = G.get(v).get(i); int u = e.to; if (e.cap > 0 && dist[u] > dist[v] + e.cost + potential[v] - potential[u]) { dist[u] = dist[v] + e.cost + potential[v] - potential[u]; prevV[u] = v; prevE[u] = i; queue.add(new int[]{dist[u], u}); } } } if (dist[t] == INF) { return -1; } for (int v = 0; v < V; v++) potential[v] += dist[v]; int d = flow; for (int v = t; v != s; v = prevV[v]) d = Math.min(d, G.get(prevV[v]).get(prevE[v]).cap); flow -= d; cost += d * potential[t]; for (int v = t; v != s; v = prevV[v]) { Edge e = G.get(prevV[v]).get(prevE[v]); e.cap -= d; G.get(v).get(e.rev).cap += d; } } return cost; } } }