結果
問題 | No.177 制作進行の宮森あおいです! |
ユーザー | startcpp |
提出日時 | 2015-04-03 00:23:13 |
言語 | C++11 (gcc 11.4.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,109 bytes |
コンパイル時間 | 739 ms |
コンパイル使用メモリ | 83,600 KB |
実行使用メモリ | 16,824 KB |
最終ジャッジ日時 | 2024-07-04 01:29:58 |
合計ジャッジ時間 | 7,134 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | TLE | - |
testcase_01 | -- | - |
testcase_02 | -- | - |
testcase_03 | -- | - |
testcase_04 | -- | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
ソースコード
//一人が複数の人と結びつくことはできる!でも相性の悪い人とはだめ… //作画同士や原画同士はやり取りなし。 //1方向に作業がすすむ。ってことは、最大フローがW以上になるかどうかだよね、グラフは2部マッチングみたいに作る。 //ただし流量を1ではなくて、JiとかXiとかにする。(フロー初めて) //しかし、フローってNP-Hardじゃないんだよなー(ググった、不思議だ //…フローなのは一瞬で分かったけど、フローってどうやるんだ!?(フローに対する考察不足, 初実装) #include<iostream> #include<string> #include<algorithm> #include<functional> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; int w; int n; int J[50]; int m; int C[50]; int ok[50][50]; //ok[J][C] int Q, X; int flow[114][114] = {0}; //増加道を探す、ある:1,ない:0を返す、一応prevを更新するので、これを使って適当に経路復元してくれ bool get_incway(int s, int t, int *prev) { queue<int> que; bool gone[114] = {false}; que.push(s); while(!que.empty() ) { int v = que.front(); que.pop(); if ( gone[v] ) continue; //cout << v << endl; gone[v] = true; for(int i = 0; i <= n+m+1; i++ ) { if ( flow[v][i] >= 1 && prev[v] != i ) { prev[i] = v; que.push(i); } } } return gone[t]; } int Maxflow(int s, int t) { int prev[114]; //prev[i] = iの前に行ったノード int ans = 0; while( get_incway(s, t, prev) ) { //フロー量のカウント ans++; //残余ネットワークを作るとかフロー流すとか int no = t; //cout << endl; while( prev[no] != s ) { //cout << "no = " << no << endl; flow[ prev[no] ][no]--; //フロー流す flow[no][ prev[no] ]++; //残余ネットワーク増やす no = prev[no]; } //最大フローじゃなくてもいいじゃん、w以上かどうかしか見てないじゃん if ( ans >= w ) break; } return ans; } //node[0]…始点、node[n+m+1]…終点、有向グラフ(が基本) (逆辺は残余ネットワークとして用いる) signed main() { int i, j; cin >> w; cin >> n; for( i = 0; i < n; i++ ) { cin >> J[i]; flow[0][i+1] = J[i]; } cin >> m; for( i = 0; i < m; i++ ) { cin >> C[i]; } for( i = 0; i < m; i++ ) { cin >> Q; for( j = 0; j < n; j++ ) { ok[j][i] = 1; } for( j = 0; j < Q; j++ ) { cin >> X; X--; ok[X][i] = 0; } } for( i = 0; i < n; i++ ) { for( j = 0; j < m; j++ ) { if ( ok[i][j] ) { //cout << i << " " << j << endl; flow[i+1][n+1+j] = J[i]; } } } for( i = 0; i < m; i++ ) { flow[n+1+i][n+m+1] = C[i]; } /*for( i = 0; i < n+m+2; i++ ) { for( j = 0; j < n+m+2; j++ ) { cout << flow[i][j] << " " ; } cout << endl; }*/ //最大フローを求める int maxf = Maxflow(0, n+m+1); if ( maxf >= w ) cout << "SHIROBAKO" << endl; else cout << "BANSAKUTSUKITA" << endl; return 0; }