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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
import java.io.*; import java.util.*; public class Main {
static char[][] mp; static int[] match; static boolean[] vis; static int n,cnt,sum; final static int[][] dir={ {-1,0},{1,0},{0,-1},{0,1}}; final static int maxn=605; static Vector<Integer>[] adj=new Vector[maxn*maxn>>1]; static HashMap<Integer, Integer> sta=new HashMap<Integer,Integer>(); static HashMap<Integer, Integer> stb=new HashMap<Integer,Integer>(); static int geta(Pt p){ int hash=p.hashCode(); if (sta.containsKey(hash)) return sta.get(hash); else{ sta.put(hash, ++cnt); return cnt; } } static int getb(Pt p){ int hash=p.hashCode(); if (stb.containsKey(hash)) return stb.get(hash); else{ stb.put(hash, ++sum); return sum; } } static boolean cango(int x,int y){ if (x<0||x>=n||y<0||y>=n||mp[x][y]!='#') return false; return true; } static boolean dfs(int u){ for(int v:adj[u]){ if (vis[v]) continue; vis[v]=true; if (match[v]<0||dfs(match[v])){ match[v]=u; return true; } } return false; } static int maxmatch(){ int res=0; Arrays.fill(match, -1); for(int i=1;i<=cnt;i++){ Arrays.fill(vis, false); if (dfs(i)) res++; } return res; } public static void main(String[] args) throws IOException{ InputReader in=new InputReader(System.in); PrintWriter out=new PrintWriter(System.out); for(int i=0;i<maxn*maxn>>1;i++) adj[i]=new Vector<Integer>(); int T=in.nextInt(),cas=0; while(T-->0){ n=in.nextInt(); mp=new char[n][n]; for(int i=0;i<n*n>>1;i++) adj[i].clear(); sta.clear();stb.clear();cnt=sum=0; for(int i=0;i<n;i++){ String s=in.next(); for(int j=0;j<n;j++) mp[i][j]=s.charAt(j); } for(int i=0;i<n;i++) for(int j=0;j<n;j++) if (mp[i][j]=='#'){ Pt p=new Pt(i, j,n); for(int k=0;k<4;k++){ int x=i+dir[k][0]; int y=j+dir[k][1]; if (((x+y)&1)>0&&cango(x,y)){ Pt q=new Pt(x, y,n); adj[geta(p)].add(getb(q)); } } } match=new int[sum+1]; vis=new boolean[sum+1]; out.println("Case "+(++cas)+": "+maxmatch()); } out.flush(); out.close(); }
} class Pt{ int x,y,n; Pt(int _x,int _y,int _n){ x=_x;y=_y;n=_n; } Pt(int hash,int _n){ n=_n; y=hash%n; x=hash/n; } public int hashCode(){ return x*n+y; } } class InputReader{ public BufferedReader reader; public StringTokenizer tokenizer; public InputReader(InputStream stream){ reader = new BufferedReader(new InputStreamReader(stream), 32768); tokenizer = null; } public String next(){ while(tokenizer == null || !tokenizer.hasMoreTokens()){ try{ tokenizer = new StringTokenizer(reader.readLine()); }catch (IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } public long nextLong() { return Long.parseLong(next()); } }
|