結果

問題 No.177 制作進行の宮森あおいです!
ユーザー yuppe19 😺yuppe19 😺
提出日時 2017-02-05 16:57:13
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 2 ms / 2,000 ms
コード長 5,741 bytes
コンパイル時間 1,053 ms
コンパイル使用メモリ 93,276 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-08-25 20:27:44
合計ジャッジ時間 1,995 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 2 ms
4,380 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 1 ms
4,376 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 2 ms
4,376 KB
testcase_07 AC 2 ms
4,380 KB
testcase_08 AC 2 ms
4,376 KB
testcase_09 AC 2 ms
4,380 KB
testcase_10 AC 2 ms
4,376 KB
testcase_11 AC 2 ms
4,376 KB
testcase_12 AC 2 ms
4,380 KB
testcase_13 AC 1 ms
4,380 KB
testcase_14 AC 2 ms
4,380 KB
testcase_15 AC 2 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <algorithm>
#include <array>
#include <tuple>
#include <queue>
using namespace std;

constexpr int inf = 987654321;

struct Edge {
  int dst, rev;
  int capa;
  int cost;
};

class Graph {
protected:
  int size;
  vector<vector<Edge>> g;
public:
  Graph(int size) : size(size) { g.resize(size); }
  void add_edge(int src, int dst, int capa);
  void add_edge(int src, int dst, int capa, int cost);
  int max_flow(int s, int t) { throw; }
  int min_cost_flow_ford(int s, int t, int flow); // ベルマンフォード
  int min_cost_flow_dijk(int s, int t, int flow); // ダイクストラ
};

class FordFulkerson : public Graph {
  vector<bool> used;
  int dfs(int v, int t, int flow);
public:
  FordFulkerson(int size) : Graph(size) {}
  int max_flow(int s, int t);
};

class Dinic : public Graph {
  vector<int> level, iter;
  void bfs(int s);
  int dfs(int v, int t, int flow);
public:
  Dinic(int size) : Graph(size) {}
  int max_flow(int s, int t);
};

void Graph::add_edge(int src, int dst, int capa) {
  add_edge(src, dst, capa, 0);
}

void Graph::add_edge(int src, int dst, int capa, int cost) {
  g[src].push_back(Edge({dst, int(g[dst].size()),   capa,  cost}));
  g[dst].push_back(Edge({src, int(g[src].size())-1,    0, -cost}));
}

int Graph::min_cost_flow_ford(int s, int t, int flow) {
  int res = 0;
  vector<int> prev_v(size), prev_e(size);
  vector<int> dist;
  while(flow > 0) {
    dist.assign(size, inf);
    dist[s] = 0;
    bool update = true;
    while(update) {
      update = false;
      for(int v=0; v<size; ++v) {
        if(dist[v] == inf) { continue; }
        for(int i=0, n=g[v].size(); i<n; ++i) {
          Edge& e = g[v][i];
          if(e.capa > 0 && dist[e.dst] > dist[v] + e.cost) {
            dist[e.dst] = dist[v] + e.cost;
            prev_v[e.dst] = v;
            prev_e[e.dst] = i;
            update = true;
          }
        }
      }
    }
    if(dist[t] == inf) { return inf; }
    int d = flow;
    for(int v=t; v!=s; v=prev_v[v]) {
      d = min(d, g[prev_v[v]][prev_e[v]].capa);
    }
    flow -= d;
    res += d * dist[t];
    for(int v=t; v!=s; v=prev_v[v]) {
      Edge& e = g[prev_v[v]][prev_e[v]];
      e.capa -= d;
      g[v][e.rev].capa += d;
    }
  }
  return res;
}

int Graph::min_cost_flow_dijk(int s, int t, int flow) {
  int res = 0;
  vector<int> prev_v(size), prev_e(size);
  vector<int> h(size);
  while(flow > 0) {
    vector<int> dist(size, inf);
    dist[s] = 0;
    queue<pair<int, int>> que;
    // 最短距離、番号
    que.emplace(0, s);
    while(!que.empty()) {
      int c, v; tie(c, v) = que.front(); que.pop();
      if(dist[v] < c) { continue; }
      for(int i=0; i<g[v].size(); ++i) {
        Edge& e = g[v][i];
        if(e.capa > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
          dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
          prev_v[e.dst] = v;
          prev_e[e.dst] = i;
          que.emplace(dist[e.dst], e.dst);
        }
      }
    }
    if(dist[t] == inf) { return inf; }
    for(int v=0; v<size; ++v) { h[v] += dist[v]; }
    int d = flow;
    for(int v=t; v!=s; v=prev_v[v]) {
      d = min(d, g[prev_v[v]][prev_e[v]].capa);
    }
    flow -= d;
    res += d * h[t];
    for(int v=t; v!=s; v=prev_v[v]) {
      Edge& e = g[prev_v[v]][prev_e[v]];
      e.capa -= d;
      g[v][e.rev].capa += d;
    }
  }
  return res;
}

int FordFulkerson::dfs(int v, int t, int flow) {
  if(v == t) { return flow; }
  used[v] = true;
  for(Edge& e : g[v]) {
    if(used[e.dst] || e.capa <= 0) { continue; }
    int d = dfs(e.dst, t, min(flow, e.capa));
    if(d > 0) {
      e.capa -= d;
      g[e.dst][e.rev].capa += d;
      return d;
    }
  }
  return 0;
}

int FordFulkerson::max_flow(int s, int t) {
  int res = 0;
  while(true) {
    used.assign(size, false);
    int flow = dfs(s, t, inf);
    if(flow == 0) { return res; }
    res += flow;
    if(res >= inf) { return inf; }
  }
}

void Dinic::bfs(int s) {
  level.assign(size, -1);
  queue<int> que;
  level[s] = 0;
  que.push(s);
  while(!que.empty()) {
    int v = que.front(); que.pop();
    for(Edge& e : g[v]) {
      if(e.capa > 0 && level[e.dst] < 0) {
        level[e.dst] = level[v] + 1;
        que.push(e.dst);
      }
    }
  }
}

int Dinic::dfs(int v, int t, int flow) {
  if(v == t) { return flow; }
  for(int& i=iter[v], n=g[v].size(); i<n; ++i) {
    Edge& e = g[v][i];
    if(e.capa <= 0 || level[v] >= level[e.dst]) { continue; }
    int d = dfs(e.dst, t, min(flow, e.capa));
    if(d > 0) {
      e.capa -= d;
      g[e.dst][e.rev].capa += d;
      return d;
    }
  }
  return 0;
}

int Dinic::max_flow(int s, int t) {
  int res = 0;
  while(true) {
    bfs(s);
    if(level[t] < 0) { return res; }
    iter.assign(size, 0);
    int flow;
    while((flow = dfs(s, t, inf)) > 0) {
      res += flow;
      if(res >= inf) { return inf; }
    }
  }
}

int main(void) {
  int w, n; scanf("%d%d", &w, &n);
  vector<int> J(n);
  for(int i=0; i<n; ++i) { scanf("%d", &J[i]); }
  int m; scanf("%d", &m);
  vector<int> C(m);
  for(int i=0; i<m; ++i) { scanf("%d", &C[i]); }
  vector<vector<bool>> G(n, vector<bool>(m, true)); // G[n][m]
  for(int i=0; i<m; ++i) {
    int q; scanf("%d", &q);
    for(int j=0; j<q; ++j) {
      int x; scanf("%d", &x);
      G[--x][i] = false;
    }
  }
  Dinic graph(n + m + 2);
  int s = n + m, t = s + 1;
  for(int i=0; i<n; ++i) {
    graph.add_edge(s, i, J[i]);
  }
  for(int i=0; i<m; ++i) {
    graph.add_edge(n+i, t, C[i]);
  }
  for(int i=0; i<n; ++i) {
    for(int j=0; j<m; ++j) {
      if(G[i][j]) {
        graph.add_edge(i, n+j, inf);
      }
    }
  }
  int min_cut = graph.max_flow(s, t);
  bool able = min_cut >= w;
  puts(able ? "SHIROBAKO" : "BANSAKUTSUKITA");
  return 0;
}
0