結果
問題 | No.177 制作進行の宮森あおいです! |
ユーザー |
![]() |
提出日時 | 2015-08-19 13:39:27 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 5,970 bytes |
コンパイル時間 | 1,736 ms |
コンパイル使用メモリ | 180,672 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-18 10:29:49 |
合計ジャッジ時間 | 1,915 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 13 |
ソースコード
#include <bits/stdc++.h>using namespace std;struct Edge {typedef int CostType;const static int cost = 1;int from, to;Edge(int from, int to) : from(from), to(to) {};};template<typename Cost> struct WeightedEdge : public Edge {typedef Cost CostType;Cost cost;WeightedEdge(int from, int to, Cost cost = 0) : Edge(from, to), cost(cost) {}};template<typename Capacity> struct ResidualEdge : public Edge {typedef Capacity CapacityType;Capacity cap;int rev;ResidualEdge(int from, int to, Capacity cap) : Edge(from, to), cap(cap) {}ResidualEdge reverse() const {return ResidualEdge(to, from, 0);}};template<typename Capacity, typename Cost> struct WeightedResidualEdge : public ResidualEdge<Capacity> {Cost cost;WeightedResidualEdge(int from, int to, Capacity cap, Cost cost) : ResidualEdge<Capacity>(from, to, cap), cost(cost) {}WeightedResidualEdge reverse() const {return WeightedResidualEdge(this->to, this->from, 0, -cost);}};template<typename Edge> class Graph {public:typedef Edge EdgeType;virtual int size() const = 0;template<typename... Args> void addEdge(Args...) {}template<typename... Args> void addUndirectedEdge(Args...) {}virtual vector<Edge> getEdges() const = 0;virtual vector<Edge> getEdges(int from) const = 0;virtual vector<Edge> getEdges(int from, int to) const = 0;virtual int getDegree(int v) const = 0;};template<typename Edge> class AdjacencyList : public Graph<Edge> {protected:vector<vector<Edge>> graph;public:AdjacencyList(int n) : graph(n) {}int size() const {return graph.size();}template<typename... Args> void addEdge(Args... args) {Edge edge(args...);graph[edge.from].emplace_back(edge);}template<typename... Args> void addUndirectedEdge(Args... args) {Edge edge(args...);addEdge(edge);swap(edge.from, edge.to);addEdge(edge);}vector<Edge> getEdges() const {vector<Edge> res;for (const auto& edges : graph) {res.insert(res.end(), edges.begin(), edges.end());}return res;}vector<Edge> getEdges(int from) const {return graph[from];}vector<Edge> getEdges(int from, int to) const {vector<Edge> res;for (const auto& edge : graph[from]) {if (edge.to == to) res.emplace_back(edge);}return res;}int getDegree(int v) const {return graph[v].size();}vector<Edge>& operator[](int v) {return graph[v];}};template<typename Edge> class ResidualGraph : public AdjacencyList<Edge> {public:ResidualGraph(int n) : AdjacencyList<Edge>(n) {}template<typename... Args> void addEdge(Args... args) {Edge edge(args...);edge.rev = this->graph[edge.to].size();this->graph[edge.from].emplace_back(edge);Edge rev = edge.reverse();rev.rev = this->graph[rev.to].size() - 1;this->graph[rev.from].emplace_back(rev);}template<typename... Args> void addUndirectedEdge(Args... args) {Edge edge(args...);edge.rev = this->graph[edge.to].size();this->graph[edge.from].emplace_back(edge);Edge rev = edge.reverse();rev.rev = this->graph[rev.to].size() - 1;rev.cap = edge.cap;this->graph[rev.from].emplace_back(rev);}void flow(int v, int i, typename Edge::CapacityType f) {auto& e = this->graph[v][i];e.cap -= f;this->graph[e.to][e.rev].cap += f;}};class MaxFlow {private:template<typename Capacity> class Dinic {private:const Capacity INF;ResidualGraph<ResidualEdge<Capacity>>& graph;vector<int> level, iter;void bfs(int source) {fill(level.begin(), level.end(), -1);level[source] = 0;queue<int> que;que.push(source);while (!que.empty()) {int v = que.front();que.pop();for (const auto& edge : graph[v]) {if (edge.cap == 0 || level[edge.to] >= 0) continue;level[edge.to] = level[v] + 1;que.push(edge.to);}}}int dfs(int v, int sink, int flow) {if (v == sink) return flow;for (int& i = iter[v]; i < int(graph[v].size()); ++i) {auto& edge = graph[v][i];if (edge.cap == 0 || level[v] >= level[edge.to]) continue;int f = dfs(edge.to, sink, min(flow, edge.cap));if (f == 0) continue;graph.flow(v, i, f);return f;}return 0;}public:Dinic(ResidualGraph<ResidualEdge<Capacity>>& graph) : INF(numeric_limits<Capacity>::max()), graph(graph) {}Capacity solve(int source, int sink) {level = vector<int>(graph.size(), 0);iter = vector<int>(graph.size(), 0);int flow = 0, f;while (true) {bfs(source);if (level[sink] < 0) return flow;fill(iter.begin(), iter.end(), 0);while ((f = dfs(source, sink, INF)) > 0) flow += f;}}};public:template<typename Capacity> Capacity solve(ResidualGraph<ResidualEdge<Capacity>>& graph, int source, int sink) {Dinic<Capacity> dinic(graph);return dinic.solve(source, sink);}};int main() {int w, n;cin >> w >> n;ResidualGraph<ResidualEdge<int>> graph(w + n + 2);int id = 0;int source = id++;int sink = id++;vector<int> a(n);for (int& i : a) i = id++;for (int i = 0; i < n; ++i) {int j;cin >> j;graph.addEdge(source, a[i], j);}int m;cin >> m;vector<int> b(m);for (int& i : b) i = id++;for (int i = 0; i < m; ++i) {int c;cin >> c;graph.addEdge(b[i], sink, c);}for (int i = 0; i < m; ++i) {int q;cin >> q;unordered_set<int> x;for (int j = 0; j < q; ++j) {int k;cin >> k;x.insert(k - 1);}for (int j = 0; j < n; ++j) {if (x.count(j)) continue;graph.addEdge(a[j], b[i], w);}}MaxFlow mf;cout << (mf.solve(graph, source, sink) >= w ? "SHIROBAKO" : "BANSAKUTSUKITA") << endl;}