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; }         }     } }
   |