結果

問題 No.177 制作進行の宮森あおいです!
ユーザー kkktym
提出日時 2022-01-23 16:51:50
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 12 ms / 2,000 ms
コード長 8,698 bytes
コンパイル時間 1,621 ms
コンパイル使用メモリ 122,772 KB
最終ジャッジ日時 2025-01-27 15:01:19
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 13
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <limits>
#include <bitset>
#define rep(i,n) for(int i = 0; i < n; ++i)
#define rep1(i,n) for(int i = 1; i <= n; ++i)
//#define rev(i,s,t) for(int i = s; i >= t; --i)
using namespace std;
template<class T>bool chmax(T &a, const T &b) { if(a < b){ a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if(a > b){ a = b; return 1; } return 0; }
template<class T> inline int sz(T &a) { return a.size(); }
using ll = long long; using ld = long double;
using pi = pair<int,int>; using pl = pair<ll,ll>;
using vi = vector<int>; using vvi = vector<vi>;
using vl = vector<ll>; using vvl = vector<vl>;
using PQ = priority_queue<int, vi, greater<int>>;
const int inf = numeric_limits<int>::max();
const ll infll = numeric_limits<ll>::max();
vi dx = {1, 0, -1, 0};
vi dy = {0, 1, 0, -1};
template<typename T>
struct Vec2 {
T X; T Y;
bool operator == (const Vec2& r) const { return (X == r.X && Y == r.Y); }
bool operator != (const Vec2& r) const { return !(*this == r); }
bool operator < (const Vec2& r) const { if(X == r.X) return Y < r.Y; return X < r.X; }
bool operator > (const Vec2& r) const { if(X == r.X) return Y > r.Y; return X > r.X; }
};
// Modint
// modint<MOD>
template<long long MOD>
struct modint{
long long x;
long long mod = MOD;
modint(long long x=0):x(x%MOD){}
modint& operator+=(const modint a){ if((x+=a.x)>=MOD) x-=MOD; return *this; }
modint& operator-=(const modint a){ if((x += MOD-a.x)>=MOD) x-=MOD; return *this; }
modint& operator*=(const modint a){ (x*=a.x)%=MOD; return *this; }
modint operator+(const modint a) const{ modint res(*this); return res+=a; }
modint operator-(const modint a) const{ modint res(*this); return res-=a; }
modint operator*(const modint a) const{ modint res(*this); return res*=a; }
modint pow(long long t) const{ if(!t) return 1; modint a = pow(t>>1); a*=a; if(t&1) a*=*this; return a; }
modint inv() const{ return pow(MOD-2); }
modint& operator/=(const modint a){ return (*this) *= a.inv(); }
modint operator/(const modint a) const{ modint res(*this); return res/=a; }
};
using mint = modint<1000000007>;
using mint998 = modint<998244353>;
using vm = vector<mint>;
using vmm = vector<vm>;
using vm998 = vector<mint998>;
using vmm998 = vector<vm998>;
const int NMAX=1000010; // we can calculate nCk until n is equal to NMAX
mint fact[NMAX],infac[NMAX];
void Make_Fact(){ fact[0]=fact[1]=1; for(int i=2;i<=NMAX-1;++i){ fact[i]=fact[i-1]*(mint)i;}}
void Make_InvFact(){ infac[0]=infac[1]=1; for(int i=2;i<=NMAX-1;++i){ infac[i]=infac[i-1]/(mint)i;}}
mint Comb(int n,int k){ if(n<0||k<0||n-k<0) return 0; return fact[n]*infac[k]*infac[n-k]; }
//----------------------------
//
// 使
///********************************
// auto f = [&](int a,int b){ return a+b;}; // :
// int id = 0; //:0
// SegTree<decltype(f),int> seg(f,id);
//************************************
//----------------------------
template <typename F,typename T>
struct SegTree{
T identity; F merge; int size; vector<T> dat; // merge,identify
SegTree(F f,T id):merge(f),identity(id){} // fid
void init(int n){ size = 1; while(size<=n) size *= 2; dat.resize(size*2-1,identity); } // nsizen2
      
void build(vector<T> vec){ rep(i,vec.size()) dat[size-1+i] = vec[i]; dfs(0); } // 0(n)
T dfs(int k){ if(k>=size-1) return dat[k]; else return dat[k] = merge(dfs(2*k+1),dfs(2*k+2)); }
// index ka
void update(int k,T a){ k += size - 1; dat[k] = a; while(k > 0){ k = (k-1)/2; dat[k] = merge(dat[2*k+1],dat[2*k+2]); } }
// index ka
void add(int k,T a){ k += size - 1; dat[k] += a; while(k > 0){ k = (k-1)/2; dat[k] = merge(dat[2*k+1],dat[2*k+2]); }}
// [a,b)(k,l,r)=(0,0,size)
T query(int a,int b,int k,int l,int r){ if(r<=a||b<=l) return identity; if(a<=l&&r<=b) return dat[k]; else return merge(query(a,b,2*k+1,l,(l+r)/2
      ),query(a,b,2*k+2,(l+r)/2,r)); }
T query(int a,int b){ return query(a, b, 0, 0, size); }
//
void show(){ int index = 0; int num = 1; while(index<size){ rep(i,num){ if(dat[i+index]==identity) cout << "e "; else cout << dat[i+index] << " ";
      } cout << "\n"; num *= 2; index = index*2+1; }}
};
struct UFT{
vector<int> par;//
vector<int> rank;//
vector<int> size;//
int n;
UFT(int _n) { n = _n; par.resize(n); rank.assign(n,0); size.assign(n,1); rep(i,n){ par[i] = i; }}
//x
int find(int x) { if(par[x] == x) return x; else return par[x] = find(par[x]);}
//x,y
void unite(int x,int y) {
x = find(x);
y = find(y);
if(x == y) return;
if(rank[x] < rank[y]){
par[x] = y;
size[y] += size[x];
}
else{
par[y] = x;
size[x] += size[y];
if(rank[x] == rank[y]) rank[x]++;
}
}
//x,y
bool same(int x,int y) { return find(x) == find(y); }
//x
int usize(int x) { return size[find(x)]; }
};
//****************************************
// MaxFlow
// Graph<X> gp(n);
// gp.add_edge(from, to, capacity);
// max_flow(s, t);
//****************************************
// status of edge
template <typename X>
struct Edge{
int from, to;
int rev; //
X cap; //
Edge() = default;
Edge(int from, int to, int rev, X cap) : from(from), to(to), rev(rev), cap(cap) {}
};
// status of node
template <typename X>
struct Node{
int idx;
vector<Edge<X>> edge;
//map<int,int> idtable; // map[to] = val: node[idx]node[to]edgeindex
Node() = default;
explicit Node(int idx) : idx(idx) {}
};
template <typename X>
class Graph{
private:
int n; // number of node
int m; // number of edge
vector<Node<X>> node;
X inf = numeric_limits<X>::max();
void Init_Node() {
rep(i,n) node.emplace_back(i);
}
public:
explicit Graph(int n) : n(n) {
Init_Node();
}
// cap
void add_edge(int from, int to, X cap) {
node[from].edge.emplace_back(from, to, node[to].edge.size(), cap);
//node[from].idtable[to] = node[from].edge.size() - 1;
node[to].edge.emplace_back(to, from, node[from].edge.size() - 1, 0);
//node[to].idtable[from] = node[to].edge.size() - 1;
}
// from->to(Edge<>)
// Edge<X> get_edge(int from, int to) {
// return node[from].edge[node[from].idtable[to]];
// }
// s->t
X max_flow(int s, int t) {
vi level(n);
vi iter(n);
auto bfs = [&]() {
level.assign(n, -1);
queue<int> q;
level[s] = 0;
q.push(s);
while( !q.empty() ) {
int v = q.front(); q.pop();
for(auto next: node[v].edge) {
if(next.cap > 0 && level[next.to] < 0) {
level[next.to] = level[v] + 1;
q.push(next.to);
}
}
}
};
auto dfs = [&](auto func, int v, X f) {
if(v == t) return f;
for(int &i = iter[v]; i < node[v].edge.size(); ++i) {
Edge<X> &e = node[v].edge[i];
if(e.cap > 0 && level[v] < level[e.to]) {
X d = func(func, e.to, min(f, e.cap));
if(d > 0) {
e.cap -= d;
node[e.to].edge[e.rev].cap += d;
return d;
}
}
}
return (X)0;
};
// main
X flow = 0;
for(;;) {
bfs();
if(level[t] < 0) return flow;
iter.assign(n, 0);
X f;
while((f = dfs(dfs, s, inf)) > 0) {
flow += f;
}
}
}
};
void Solve(){
int w; cin >> w;
int n,m; cin >> n;
vi a(n);
rep(i,n) cin >> a[i];
cin >> m;
vi c(m);
rep(i,m) cin >> c[i];
vector<map<int,int>> mp(m);
rep(i,m) {
int q; cin >> q;
rep(j,q) {
int x; cin >> x;
x--;
mp[i][x] = 1;
}
}
Graph<int> gp(n*2+m*2+2);
rep(i,n) {
gp.add_edge(i, n+m+i, a[i]);
gp.add_edge(2*n+2*m, i, inf);
}
rep(i,m) {
gp.add_edge(n+i, 2*n+m+i, c[i]);
gp.add_edge(2*n+m+i, 2*n+2*m+1, inf);
}
rep(i,n) {
rep(j,m) {
if(mp[j].find(i) == mp[j].end()) {
gp.add_edge(n+m+i, n+j, inf);
}
}
}
int res = gp.max_flow(2*n+2*m, 2*n+2*m+1);
cout << (res >= w ? "SHIROBAKO" : "BANSAKUTSUKITA") << "\n";
}
int main()
{
Solve();
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0