首页 > 代码库 > ZOJ 1654 Place the Robots

ZOJ 1654 Place the Robots

题目大意:

在空地上放置尽可能多机器人,机器人朝上下左右4个方向发射子弹,子弹能穿过草地,但不能穿过墙,

两个机器人之间的子弹要保证互不干扰,求所能放置的机器人的最大个数

 

每个机器人所在的位置确定了,那么对应的横向和竖向子弹能到达的空地就全部被覆盖了

我们将横向所能连接在一块的空地区域标上同一个标号

比如o*o#o , 就可标号为10102因为1,3空地中间的草地不影响子弹的穿越

同理,我们将竖向的所能连接在一块的空地区域标上同一个标号

 

那么就可以建立一个横向到达竖向的二部图匹配

每次成功匹配一对,就相当于在这横竖交叉处放了一个炮台

 

这就转化成了最大匹配数

 

 1 #include <cstdio> 2 #include <cstring> 3  4 using namespace std; 5 const int N = 55; 6  7 char str[N][N]; 8 int n , m , xs[N][N] , ys[N][N] , idx , idy;//idx记录以行为轴的最大标号,idy则表示以列为轴的最大标号 9 int cx[N*N] , cy[N*N] , visy[N*N];10 bool g[N*N][N*N];//int是4个字节,用int会MLE,bool一个字节11 12 int dfs(int u)13 {14     for(int v = 1 ; v<=idy ; v++){15         if(g[u][v] && !visy[v]){16             visy[v] = 1;17             if(cy[v] == -1 || dfs(cy[v])){18                 cx[u] = v;19                 cy[v] = u;20                 return 1;21             }22         }23     }24     return 0;25 }26 27 int MaxMatch()28 {29     memset(cx , -1 , sizeof(cx));30     memset(cy , -1 , sizeof(cy));31     int ans = 0;32     for(int i=1 ; i<=idx ; i++){33         if(cx[i] == -1){34             memset(visy , 0 , sizeof(visy));35             ans += dfs(i);36         }37     }38     return ans;39 }40 41 int main()42 {43   //  freopen("a.in" , "r" , stdin);44     int T , cas = 0;45     scanf("%d" , &T);46     while(T--)47     {48         scanf("%d%d" , &n , &m);49         for(int i = 0 ; i<n ; i++)50             scanf("%s" , str[i]);51 52         //给每行炮台所能触及的位置编为相同号53         int id = 1 , flag = 0;54         for(int i=0 ; i<n ; i++){55             if(flag) flag = 0 , id++;56             for(int j = 0 ; j < m ; j++){57                 if(str[i][j] == o)58                     xs[i][j] = id , idx = id , flag = 1;59                 else if(str[i][j] == #)60                     flag = 0 , id++;61             }62         }63 64         //给每列炮台所能触及的位置编为相同号65         id = 1 , flag = 0;66         for(int i=0 ; i<m ; i++){67             if(flag) flag = 0 , id++;68             for(int j = 0 ; j < n ; j++){69                 if(str[j][i] == o)70                     ys[j][i] = id , idy = id , flag = 1;71                 else if(str[j][i] == #)72                     flag = 0 , id++;73             }74         }75 76         //构造二部图77         memset(g , 0 , sizeof(g));78         for(int i = 0 ; i<n ; i++)79             for(int j = 0 ; j<m ; j++){80                 if(str[i][j] == o)81                     g[xs[i][j]][ys[i][j]] = true;82             }83         printf("Case :%d\n%d\n" , ++cas , MaxMatch());84     }85     return 0;86 }

 

ZOJ 1654 Place the Robots