1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "queue" using namespace std; #define MAXN 5006 #define inf 0x3f3f3f3f const int QWQ = 3006; class mincmaxf { #define maxn 50005 public: #define N 5010 #define M 100006 #define INF 0x3f3f3f3f int tot, lnk[N], cur[N], ter[M], nxt[M], cap[M], cost[M], dis[N], ret; bool vis[N]; void init( ) { tot = 1; memset( lnk , 0 , sizeof lnk ) , memset( cur , 0 , sizeof cur ); ret = 0; } int add(int u, int v, int w, int c) { ter[++tot] = v, nxt[tot] = lnk[u], lnk[u] = tot, cap[tot] = w, cost[tot] = c; return tot; } int Ade(int u, int v, int w, int c) { add(v, u, 0, -c); return add(u, v, w, c); } bool spfa(int s, int t) { for( int i = 1 ; i < MAXN ; ++ i ) dis[i] = -INF; memcpy(cur, lnk, sizeof(lnk)); std::queue<int> q; q.push(s), dis[s] = 0, vis[s] = 1; while (!q.empty()) { int u = q.front();
q.pop(), vis[u] = 0; for (int i = lnk[u]; i; i = nxt[i]) { int v = ter[i]; if (cap[i] && dis[v] < dis[u] + cost[i]) { dis[v] = dis[u] + cost[i]; if (!vis[v]) q.push(v), vis[v] = 1; } } } return dis[t] != -INF; } int dfs(int u, int t, int flow) { if (u == t) return flow; vis[u] = 1; int ans = 0; for (int &i = cur[u]; i && ans < flow; i = nxt[i]) { int v = ter[i]; if (!vis[v] && cap[i] && dis[v] == dis[u] + cost[i]) { int x = dfs(v, t, std::min(cap[i], flow - ans)); if (x) ret += x * cost[i], cap[i] -= x, cap[i ^ 1] += x, ans += x; } } vis[u] = 0; return ans; } int mcmf(int s, int t) { int ans = 0; while (spfa(s, t)) { int x; while ((x = dfs(s, t, INF))) ans += x; } return ret; } } F ; int n , a , b; int s = 5001 , t = 5002; char ch[MAXN][MAXN]; int main() {
int kase = 0; while( cin >> n >> a >> b ) { if( n == 0 && a == 0 && b == 0 ) return 0; for( int i = 1 ; i <= n ; ++ i ) scanf("%s",ch[i] + 1); for( int lim = n ; lim >= 0 ; -- lim ) { int c = 0; F.init( ); for (int i = 1 ; i <= n ; ++ i) { F.Ade( i , i + n , lim , 0 ); F.Ade( s , i , lim , 0 ); F.Ade( i + n , t , lim , 0 ); for (int j = 1; j <= n; ++j) { if( ch[i][j] == '.' ) F.Ade( i , j + n , 1 , 1 ); if( ch[i][j] == 'C' ) F.Ade( i , j + n , 1 , QWQ + 1 ) , ++ c; } } int ans = F.mcmf( s , t ); if( ans / QWQ < c ) { printf("Case %d: impossible\n",++ kase); break; } ans %= QWQ; if( ans * a >= lim * b ) { printf("Case %d: %d\n",++ kase , ans - c); break; } } } }
|