結果
問題 | No.177 制作進行の宮森あおいです! |
ユーザー |
|
提出日時 | 2016-06-09 21:29:35 |
言語 | Java (openjdk 23) |
結果 |
AC
|
実行時間 | 214 ms / 2,000 ms |
コード長 | 3,434 bytes |
コンパイル時間 | 3,938 ms |
コンパイル使用メモリ | 81,208 KB |
実行使用メモリ | 54,368 KB |
最終ジャッジ日時 | 2024-10-09 06:48:26 |
合計ジャッジ時間 | 7,586 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 13 |
ソースコード
import java.util.*;public class Main_yukicoder177 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int w = sc.nextInt();int n = sc.nextInt();int[] j = new int[n];for (int i = 0; i < n; i++) {j[i] = sc.nextInt();}int m = sc.nextInt();int[] c = new int[m];for (int i = 0; i < m; i++) {c[i] = sc.nextInt();}List<Set<Integer>> ng = new ArrayList<>();for (int i = 0; i < m; i++) {Set<Integer> tmp = new HashSet<>();int q = sc.nextInt();for (int k = 0; k < q; k++) {tmp.add(sc.nextInt() - 1);}ng.add(tmp);}Dinic di = new Dinic(n + m + 2);for (int i = 0; i < n; i++) {di.addEdge(0, i + 2, j[i]);}for (int i = 0; i < m; i++) {di.addEdge(i + n + 2, 1, c[i]);}for (int i = 0; i < n; i++) {for (int k = 0; k < m; k++) {if (!ng.get(k).contains(i)) {di.addEdge(i + 2, k + n + 2, w);}}}if (di.getMaxflow(0, 1) >= w) {System.out.println("SHIROBAKO");} else {System.out.println("BANSAKUTSUKITA");}sc.close();}private static class Dinic {private static final int INF = Integer.MAX_VALUE;ArrayList<Edge>[] edges;int n;@SuppressWarnings("unchecked")Dinic(int n) {this.n = n;edges = new ArrayList[n];for (int ii = 0; ii < n; ii++) {edges[ii] = new ArrayList<Edge>();}checkedTo = new int[this.n];level = new int[this.n];}// i, j:0-indexedpublic void addEdge(int i, int j, int c) {edges[i].add(new Edge(j, c, edges[j].size(), false));// add reverse edgeedges[j].add(new Edge(i, c, edges[i].size() - 1, true));}public int getMaxflow(int s, int t) {// initialize flowfor (int i = 0; i < edges.length; i++) {for (Edge e : edges[i]) {if (!e.revFlag) {e.f = 0;} else {e.f = e.w;}}}int ret = 0;while (true) {Arrays.fill(level, -1);bfs(s);if (level[t] == -1) {break;}Arrays.fill(checkedTo, 0);int augmentation;while ((augmentation = dfs(s, t, INF)) > 0) {ret += augmentation;}}return ret;}private static int[] checkedTo;private static int[] level;// no capacity edges must be removedprivate void bfs(int s) {Queue<Integer> q = new ArrayDeque<Integer>();level[s] = 0;q.add(s);while (!q.isEmpty()) {int u = q.remove();for (Edge e : edges[u]) {if (level[e.v] == -1 && e.w - e.f > 0) {level[e.v] = level[u] + 1;q.add(e.v);}}}}// find max flow (less than f), on u -> v path// next vertex must has larger levelprivate int dfs(int u, int v, int f) {if (u == v) {return f;}for (; checkedTo[u] < edges[u].size(); checkedTo[u]++) {Edge e = edges[u].get(checkedTo[u]);if (level[e.v] > level[u] && e.w - e.f > 0) {int a = dfs(e.v, v, Math.min(f, e.w - e.f));if (a != 0) {e.f += a;edges[e.v].get(e.revIndex).f -= a;return a;}}}return 0;}private static class Edge {// int u; // fromint v; // toint w; // costint f; // flowint revIndex; // index of reverse edgeboolean revFlag; // flag of reverse edgeEdge(int v, int w, int re, boolean f) {// this.u = u;this.v = v;this.w = w;this.f = 0;this.revIndex = re;this.revFlag = f;}}}}