题意:你大爷。哦不!

你大叔继承了一块地什么的都是废话。。,这里说说题意,和怎么建图。

题意:这里有一块N*M的地,可是有 K 个地方。是池塘,然后输入K行(x,y),OK,如今能够出售的地必须是 1*2 大小的矩形,而且不能是池塘。。。

问。在N*M的这块地上。能有多少块地能够出售,而且。要输出这些能够出售的地的坐标。

建图:那么这里事实上和我之前做过的hdu4185 差点儿相同1A。

http://blog.csdn.net/zyy173533832/article/details/12654539

那么能够预先处理一下,把N*M的地图中,是土地的按 1,2,3....编号。在这里我们须要对于每一个编号。记录这个编号的土地的坐标。那么这里他说了N*M-K <= 50。那么我们接着对于每一个土地,遍历四个方向,看看有木有能够组在一起变成能卖的地。然后。。。然后图就建好啦。

那么在二分匹配的过程中也要注意的是:匹配好的数量须要÷2,输出的时候也有点须要注意的,直接看代码中的解释:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. using namespace std;
  5.  
  6. #define MAX 105
  7.  
  8. int N,M,K;
  9. int map[MAX][MAX];
  10. int loc[MAX/2][2];//这里是依据编号记录坐标 如第2个地的坐标 (loc[2][0] , loc[2][1])
  11. int node_num; //点数,也就是土地的数量。编号的那个
  12.  
  13. struct Edge{//邻接表
  14. int to,next;
  15. }edge[MAX*4];
  16. int head[MAX/2],edge_num;
  17.  
  18. void add(int u,int v){
  19. edge[edge_num].to = v;
  20. edge[edge_num].next = head[u];
  21. head[u] = edge_num++;
  22. }
  23.  
  24. int vis[4][2]={0,1,0,-1,1,0,-1,0};
  25.  
  26. void initMap(){
  27. node_num = 1;
  28. memset(map,0,sizeof(map));
  29.  
  30. int x,y;
  31. while(K --){
  32. cin >> x >> y;
  33. map[x][y] = -1;//表示此地不可用。是池塘
  34. }
  35.  
  36. for(int i = 1; i <= N; i ++){
  37. for(int j = 1; j <= M; j ++){
  38. if(!map[i][j]) {
  39. map[i][j] = node_num++;
  40. loc[node_num-1][0] = i; loc[node_num-1][1] = j;//记录坐标
  41. }
  42. }
  43. }
  44.  
  45. edge_num = 0;
  46. memset(head,-1,sizeof(head));
  47. for(int i = 1; i <= N; i ++){
  48. for(int j = 1; j <= M; j ++){
  49. if(map[i][j] != -1){
  50. for(int k = 0; k < 4; k ++)
  51. {
  52. int x = i+vis[k][0],y = j+vis[k][1];
  53. if(map[x][y] != -1 && x >=1 && y >= 1 && x <= N && y <= M)
  54. {
  55. add(map[i][j],map[x][y]); add(map[x][y],map[i][j]);
  56. }
  57. }
  58. }
  59. }
  60. }
  61. }
  62. //------------------------
  63. bool useif[MAX/2];
  64. int link[MAX/2];
  65. bool dfs(int u){
  66. for(int i = head[u]; i != -1; i = edge[i].next){
  67. int v = edge[i].to;
  68. if(!useif[v]){
  69. useif[v] = true;
  70. if(link[v] == -1 || dfs(link[v]))
  71. {
  72. link[v] = u;
  73. return true;
  74. }
  75. }
  76. }
  77. return false;
  78. }
  79. void match(){
  80. int ans_num = 0;
  81. memset(link,-1,sizeof(link));
  82. for(int i = 1; i <= node_num; i ++){
  83. memset(useif,false,sizeof(useif));
  84. if(dfs(i)) ans_num++;
  85. }
  86.  
  87. //print
  88. cout << ans_num/2 <<endl;
  89. bool ifmatch[MAX/2]={false}; //这里是表示这个点是不是被输出过
  90. for(int i = 1; i <= node_num; i ++){
  91. if(!ifmatch[i] && link[i] != -1 && !ifmatch[link[i]]){
  92. ifmatch[i] = true; ifmatch[link[i]] = true;
  93. printf("(%d,%d)--(%d,%d)\n",loc[i][0],loc[i][1],loc[link[i]][0],loc[link[i]][1]);
  94. }
  95. }
  96. }
  97.  
  98. int main()
  99. {
  100. bool first_cas = true;//控制案例间空行
  101. while(cin >> N >> M)
  102. {
  103. if(!N && !M) break;
  104. cin >> K;
  105. initMap();
  106. if(!first_cas) cout << endl;
  107. match();
  108. first_cas = false;
  109. }
  110. return 0;
  111. }

个人愚昧观点,欢迎指正与讨论

hdu1507--二分图最大匹配的更多相关文章

  1. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  2. POJ2239 Selecting Courses(二分图最大匹配)

    题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...

  3. poj 2239 二分图最大匹配,基础题

    1.poj 2239   Selecting Courses   二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...

  4. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  5. 二分图最大匹配的K&#246;nig定理及其证明

     二分图最大匹配的K?nig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K?nig定理证了,其它的废话一概没有.    以下五个问题我可能会在以后的文章里说,如果你现在很想知道的话,网上 ...

  6. POJ3057 Evacuation(二分图最大匹配)

    人作X部:把门按时间拆点,作Y部:如果某人能在某个时间到达某门则连边.就是个二分图最大匹配. 时间可以二分枚举,或者直接从1枚举时间然后加新边在原来的基础上进行增广. 谨记:时间是个不可忽视的维度. ...

  7. ZOJ1654 Place the Robots(二分图最大匹配)

    最大匹配也叫最大边独立集,就是无向图中能取出两两不相邻的边的最大集合. 二分图最大匹配可以用最大流来解. 如果题目没有墙,那就是一道经典的二分图最大匹配问题: 把地图上的行和列分别作为点的X部和Y部, ...

  8. HDU:过山车(二分图最大匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2063 题意:有m个男,n个女,和 k 条边,求有多少对男女可以搭配. 思路:裸的二分图最大匹配,匈牙利算法. 枚 ...

  9. UOJ #78 二分图最大匹配

    #78. 二分图最大匹配 从前一个和谐的班级,有 nl 个是男生,有 nr 个是女生.编号分别为 1,…,nl 和 1,…,nr. 有若干个这样的条件:第 v 个男生和第 u 个女生愿意结为配偶. 请 ...

  10. 【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题

    学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二 ...

随机推荐

  1. CSS中的几个概念--------Day39

    世界杯疯狂来袭,让这个原本就高温的夏季瞬间被引爆了,这肆虐的激情仿佛让一切都灼热了起来,绽放着刺目的光,工作之余总有那么一群人在那激烈的讨论着争辩着,抑不住的亢奋. 非常不巧,往往这群身影中总有我的存 ...

  2. 怎样查看apk须要支持的Android版本号

    假设有一个apk,须要知道他最低安装支持的Android版本号是什么,应该怎样查看呢? 直接将apk后缀名改为rar或者zip,拉出AndroidManifest.xml?不行,AndroidMani ...

  3. JavaScript函数节流与函数去抖

    介绍 首先解释一下这两个概念: 函数节流(throttle):是让一个函数无法在很短的时间间隔内连续调用,当上一次函数执行后过了规定的时间间隔,才能进行下一次该函数的调用. 函数去抖(debounce ...

  4. 让AllocateHwnd接受一般函数地址作参数(105篇博客)

    http://www.xuebuyuan.com/1889769.html Classes单元的AllocateHWnd函数是需要传入一个处理消息的类的方法的作为参数的,原型: function Al ...

  5. 让Android中的webview支持页面中的文件上传

    android webview在默认情况下是不支持网页中的文件上传功能的: 如果在网页中有<input type="file" />,在android webview中 ...

  6. c#调用语音功能

    转自 http://www.cnblogs.com/Hans2Rose/p/WeatherSpeaker.html .Net里面自带了一个语音类库:System.Speech,调用系统的语音功能,就能 ...

  7. hdu2159 Fate 二维背包

    #include <cstring> #include <string> #include <cstdio> #include <cmath> #inc ...

  8. Andy&#39;s First Dictionary

    Description Andy, 8, has a dream - he wants to produce his very own dictionary. This is not an easy ...

  9. 二进制搜索方法C++通用执行

    算法很easy.直接附着到代码它 #include <iostream> using namespace std; template<typename T> int binar ...

  10. 解决ScrollView中的ListView无法显示全

    问题描述: ListView加入到ScrollView中之后,发现只能显示其中一条,具体原因得看一下源代码.现在先贴一下方案 (转自:http://blog.csdn.net/hitlion2008/ ...