poj3020

有一些’o’和’‘构成的图,每个可以与其四周的’‘连一条边,但是连完之后这两个‘’就称作被覆盖了,不能与其他的’‘发生交集了。 然后问用最少的边能把所有的‘’都覆盖掉

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {


    public static void main(String[] args) throws IOException{

           StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)); 
           InputReader in = new InputReader(System.in)  ;
           PrintWriter out = new PrintWriter(System.out) ;  
           int t = in.nextInt() ;
           for(int i = 0 ; i < t ; i++){
                new Task().solve(in, out) ;  
           }
           out.flush();
    }

}

class  Task{

       static int[][] id = new int[40][10] ;
       static int[][] dir = new int[][]{{-1,0},{0,-1},{1,0},{0,1}} ;

       int n , m  ;   
       char[][] grid ;


       boolean  can(int x , int y){
                return 0 <= x && x < n && 0 <= y && y < m ; 
       }

       public void solve(InputReader in , PrintWriter out) throws IOException{

              n = in.nextInt() ; 
              m = in.nextInt() ;
              grid = new char[n][m] ;
              for(int i = 0 ; i < n ; i++) grid[i] = in.next().toCharArray() ;

              int l = 0  , r = 0 ; 
              for(int i = 0 ; i < n ; i++){
                   for(int j = 0 ; j < m ; j++){
                         if(grid[i][j] == '*'){
                              if(((i+j) & 1) > 0) id[i][j] = ++l ;
                              else  id[i][j] = ++r ;
                         } 
                   }
              }

              MaxMatch solver = new MaxMatch(l, r) ;
              for(int i = 0 ; i < n ; i++){
                   for(int j = 0 ; j < m ; j++){
                         if(grid[i][j] == '*' && ((i+j)&1) > 0){
                                for(int k = 0 ; k < 4 ; k++){
                                     int x = i + dir[k][0] ;
                                     int y = j + dir[k][1] ;
                                     if(can(x, y) && grid[x][y] == '*') solver.add(id[i][j], id[x][y]) ;
                                }
                         } 
                   }
              }

              out.println(l+r - solver.getMaxmatch() ) ;

       }
}


class  MaxMatch{
       static  final  int N = 208 ;
       static  int[] g = new int[N] ;
       static  int[] next = new int[N*N] ;
       static  int[] ev = new int[N*N] ;
       static int  id ;
       void  add(int u , int v){
             ev[id] =  v ;
             next[id] = g[u] ;
             g[u] = id++ ;
       }


       int n  , m ; 
       static int[] match = new int[N] ;
       static boolean[] vis = new boolean[N] ;
       MaxMatch(int n ,  int m){
              this.n = n ; 
              this.m = m ;
              id = 0 ;
              Arrays.fill(g, 1 , n+1, -1) ;
       }

       boolean dfs(int u){
               for(int i = g[u] ; i != -1 ; i = next[i]){
                      int v = ev[i] ;
                      if(vis[v]) continue ;
                      vis[v] = true ;
                      if(match[v] == -1 || dfs(match[v])){
                            match[v] = u ;
                            return true ;
                      }
               }
               return false ;
       }

       int   getMaxmatch(){
             Arrays.fill(match, 1 , n+1 , -1) ;
             int sum = 0 ; 
             for(int u = 1 ; u <= n ; u++){
                   Arrays.fill(vis, 1 , m+1 , false) ;
                   if(dfs(u)) sum++ ;
             } 
             return sum ;
       }

}



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

        public double nextDouble(){
                    return  Double.parseDouble(next());
        }

}

你可能感兴趣的:(poj3020)