题目大意:
这个是以前做过的一道DFS题目,当时是完全暴力写的。
给你一个N代表是N*N的矩阵,矩阵内 ‘X’代表墙, ‘.’代表通道。
问这个矩阵内最多可以放几个碉堡, 碉堡不能在同一行或者同一列,除非他们中间有墙。
 
二分图做法思想:我们用行去匹配列,判断最大匹配数。
我们需要重新构图, 假如一行中 (  ..X..X.. ) 那么在这一行中我们其实是可以分割到三个不同的行(因为中间隔有X)。然后对这个三个行进行编号。同理列也是一样的。当我们完全构好图后就可以做完全匹配了,其他的跟HDU 1083 Courses(最大匹配模版题) 差不多。
吐槽一下杭电,代码写好了提交用C++WA  G++过 妈蛋
 
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. #include<iostream>
  5. using namespace std;
  6. #define maxn 50
  7. bool G[maxn][maxn];///重新构图存储
  8. bool vis[maxn];///标记点是否被遍历过
  9. char maps[maxn][maxn];///地图存储
  10. int P[maxn];///第 i 行匹配的第 P[i]列
  11. int n, m, N;///重构图后是m行 n列
  12. struct Node
  13. {
  14. int x, y;
  15. }NodeInfo[maxn][maxn];///保存每个点重构图后所在的行和列
  16.  
  17. bool Find(int u)
  18. {
  19. for(int i=; i<n; i++)
  20. {
  21. if(G[u][i] && !vis[i])
  22. {
  23. vis[i] = true;
  24. if( P[i] == - || Find(P[i]))
  25. {
  26. P[i] = u;
  27. return true;
  28. }
  29. }
  30. }
  31. return false;
  32. }
  33. void MakeMaps()
  34. {
  35. m = , n = ;///行标记 和 列标记
  36.  
  37. for(int i=; i<N; i++)///第 i 行
  38. {
  39. for(int j=; j<N; j++)
  40. {
  41. if(maps[i][j] == '.')
  42. NodeInfo[i][j].x = m;
  43. if(maps[i][j+] == 'X' || maps[i][j+] == )
  44. m ++;
  45. }
  46. }
  47.  
  48. for(int i=; i<N; i++)///第 i 列
  49. {
  50. for(int j=; j<N; j++)
  51. {
  52. if(maps[j][i] == '.')
  53. NodeInfo[j][i].y = n;
  54. if(maps[j+][i] == 'X' || maps[j+][i] == )
  55. n ++;
  56. }
  57. }
  58.  
  59. for(int i=; i<N; i++)
  60. {
  61. for(int j=; j<N; j++)
  62. {
  63. int x = NodeInfo[i][j].x;
  64. int y = NodeInfo[i][j].y;
  65.  
  66. if(maps[i][j] == '.')
  67. G[x][y] = true;
  68. }
  69. }
  70. }
  71.  
  72. int main()
  73. {
  74. while(scanf("%d", &N), N)
  75. {
  76.  
  77. memset(G, , sizeof(G));
  78. memset(P, -, sizeof(P));
  79. memset(maps, , sizeof(maps));
  80.  
  81. for(int i=; i<N; i++)
  82. scanf("%s", maps[i]);
  83.  
  84. MakeMaps();
  85. int ans = ;
  86. for(int i=; i<m; i++)
  87. {
  88. memset(vis, false, sizeof(vis));
  89. if( Find(i) )
  90. ans ++;
  91. }
  92. printf("%d\n", ans);
  93. }
  94. return ;
  95. }
 

HDU 1045 Fire Net(图匹配)的更多相关文章

  1. HDU 1045 Fire Net(行列匹配变形+缩点建图)

    题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...

  2. hdu 1045 Fire Net(二分匹配 or 暴搜)

    Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. hdu 1045 Fire Net 二分图匹配 && HDU-1281-棋盘游戏

    题意:任意两个个'车'不能出现在同一行或同一列,当然如果他们中间有墙的话那就没有什么事,问最多能放多少个'车' 代码+注释: 1 //二分图最大匹配问题 2 //难点在建图方面,如果这个图里面一道墙也 ...

  4. HDOJ(HDU).1045 Fire Net (DFS)

    HDOJ(HDU).1045 Fire Net [从零开始DFS(7)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HD ...

  5. HDU 1045 Fire Net 【连通块的压缩 二分图匹配】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    ...

  6. HDU 1045 Fire Net 二分图建图

    HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...

  7. HDU 1045(Fire Net)题解

    以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔. [题目分析] 这题本来在搜索专题 ...

  8. hdu 1045 Fire Net(最小覆盖点+构图(缩点))

    http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS     Memory Limit:32768KB   ...

  9. HDU 1045 Fire Net(dfs,跟8皇后问题很相似)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)   ...

  10. HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】

    Fire Net Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

随机推荐

  1. DFU工作过程中USB机制

    在一级bootloader执行进入USB启动方式之后,设备进行枚举.枚举过程中会通过PC端发送命令对连接的USB设备进行枚举.当枚举成功之后,在PC端可以看到设备的盘符. 当设备能够被PC正确识别之后 ...

  2. Eclipse中使用git把项目导入到osc@git中

    方便Eclipse用户使用Git把项目导入到osc@git中进行管理. Eclipse Git osc@git 一.原有项目:  项目名为TestGit 二.在osc@git上面创建一个新项目库. 填 ...

  3. Ubuntu知识记录

    1.激活root用户:sudo passwd root 2.安装ftp:apt-get install vsftpd,修改配置文件/etc/vsftpd.conf write_enable=yes表明 ...

  4. Codeforces 190E - Counter Attack

    [题意]给一个无向图的反图(即给定的边实际上不存在,而未给的边是存在的),求连通块数.(点数n<=5*10^5,边数m<=10^6) 一开始我想的用DFS,枚举每一个点,跳过不存在的点,直 ...

  5. C#中的IO流操作(FileStream)

    StreamReader和StreamWriter适用于对文本文件的操作,因为它是以字符为单位进行的操作 不用担心编码问题 using (Stream s = new FileStream(@&quo ...

  6. Linux SSH: key, agent, keychain

    以前遇到过一个问题,在用有些 Linux 发行版时,用 ssh-keygen 产生好了密钥对并上传到了目标服务器,但每次登录都要重新输入. 这与 ssh-agent 有关,看如下 man ssh-ag ...

  7. C# - 二叉树表达式计算

    很早以前就写过双栈的表达式计算. 这次因为想深入学一下二叉树,网上都是些老掉牙的关于二叉树的基本操作. 感觉如果就学那些概念,没意思也不好记忆.于是动手写了一个表达式计算的应用例子. 这样学习印象才深 ...

  8. C#接口的使用

    .接口: 接口与抽象类一样,也是表示某种规则,一旦使用了该规则,就必须实现相关的方法.对于C#语言而言,由于只能继承自一个父类,因此若有多个规则需要实现,则使用接口是个比较好的做法. .接口的定义 i ...

  9. Asp.net 事务处理

    事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...

  10. sqlcode、sqlerrm

    Oracle里 非常有用的 两个变量,很少有人用. 标记一下