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 94 95 96 97
   | #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue> #define PB push_back #define MP make_pair #define PII pair<int,int> #define FIR first #define SEC second #define ll long long using namespace std; template <class T> inline void rd(T &x) { 	x=0; char c=getchar(); int f=1; 	while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } 	while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f; } const int N=110; int S,T; namespace Flow {     int head[N],cur[N],dis[N],vis[N];     struct ed { int to,next,f,w; };     vector<ed> e;     void init() { memset(head,-1,sizeof(head)); }     void ad(int x,int y,int f,int w) {         e.PB((ed){y,head[x],f,w}); head[x]=e.size()-1;         e.PB((ed){x,head[y],0,-w}); head[y]=e.size()-1;     }     bool bfs() {         memset(dis,-0x3f,sizeof(dis));         memcpy(cur,head,sizeof(cur));         queue<int> q;         q.push(S),vis[S]=1,dis[S]=0;         while(!q.empty()) {             int u=q.front(); q.pop(),vis[u]=0;             for(int k=head[u];~k;k=e[k].next) if(e[k].f) {                 int v=e[k].to;                 if(dis[v]<dis[u]+e[k].w) {                     dis[v]=dis[u]+e[k].w;                     if(!vis[v]) vis[v]=1,q.push(v);                 }             }         }         return dis[T]>-1e9;     }     int dfs(int u,int f) {         if(u==T||!f) return f; int ret=0,tmp;         vis[u]=1;         for(int &k=cur[u];~k;k=e[k].next) if(e[k].f) {             int v=e[k].to;             if(!vis[v]&&dis[v]==dis[u]+e[k].w&&(tmp=dfs(v,min(f,e[k].f)))) {                 e[k].f-=tmp,e[k^1].f+=tmp;                 ret+=tmp,f-=tmp;                 if(!f) break;             }         }         vis[u]=0;         return ret;     }     int work() { int ans=0; while(bfs()) ans+=dis[T]*dfs(S,1e9); return ans; } } int n,A,B; char mp[55][55]; int main() { 	int ts=0; 	while(~scanf("%d%d%d",&n,&A,&B)) { 		if(!n&&!A&&!B) break; 		for(int i=1;i<=n;++i) scanf("%s",mp[i]+1); 		S=2*n+1,T=2*n+2; 		int M=n*n*n+10;  		int mx=-1; 		for(int lim=n;lim>=0;--lim) { 			Flow::init(); 			for(int i=1;i<=n;++i) 				Flow::ad(S,i,lim,0), 				Flow::ad(i,i+n,1e9,0), 				Flow::ad(i+n,T,lim,0); 			int tot=0; 			for(int i=1;i<=n;++i) 				for(int j=1;j<=n;++j) { 					if(mp[i][j]=='.') Flow::ad(i,j+n,1,1); 					if(mp[i][j]=='C') Flow::ad(i,j+n,1,M+1),tot++; 				} 			int ans=Flow::work(); 			if(ans<tot*(M+1)) continue; 			ans%=M; 			if(ans*A<lim*B) continue; 			mx=max(mx,ans-tot); 		} 		printf("Case %d: ",++ts); 		if(mx<=-1) printf("impossible\n"); 		else printf("%d\n",mx); 	} 	return 0; }
   |