刚开始看到这个题目的时候就觉得想法很明了,就是不知道如何去匹配...

去网上看了不少人的解题报告,但是对于刚接触“最小边覆盖”的我来说....还是很困难滴....于是自己又开始一如以往学习“最大独立集”、“最小点覆盖的”的思考方式啦:在了解一个看似高深的知识点之前,粗略了解这是个什么东东,那么看概念也会更好理解,(希望此博客在自己以后回头来看会一目明了,也对刚接触“最小边覆盖”的人有帮助(万分感到荣幸)):

首先把题目的第一个案例图形化(第一,图形好理解,第二,很多人看到文字就烦啦。第三,图论不画图怎么可以捏),我们把交叉路看成点,街道看成边,就如下图:

要求选择最少的伞兵降落在某些交叉口,使他们走完所有的交叉口,(注意是单向边)从图中很容易选择,我们在二号交叉口降落一个走到3再走到4,然后在1好交叉口降落一个,总共两个就可以访问所有的交叉口,我们就可以这样看:把3号街道和1号街道看做一条边,把2.3.4号交叉点都覆盖啦:如图

这样就对“最小边覆盖”有了那么点粗俗的理解啦

接下来是解决这个问题,用匈牙利匹配:因为刚开始接触二分匹配,我就想用街道(简化为点)去和交叉口匹配:(谁知道...如图)

可想而知..完全不知道怎么匹配....

接着就看看最小边覆盖和二分匹配的关系吧:(如果觉得看文字概念还是很烦..可以看下面的图形说明,不过结合文字和图形更有助理解)(摘自百度百科)

路径覆盖与
二分图匹配的关系(必须是没有圈的有向图):
最小路径覆盖=|P|-最大匹配数(|P|为定点数)
其中最大匹配数的求法是把P中的每个顶点pi分成两个顶点pi'与pj'',如果在p中存在一条pi到pj的边,那么在二分图P'中就有一条连接pi'与pj''的无向边;这里pi' 就是p中pi的出边,pj''就是p中pj 的一条入边;
对于
公式:最小路径覆盖=|P|-最大匹配数;可以这么来理解;
如果匹配数为零,那么P中不存在有向边,于是显然有:
最小路径覆盖=|P|-最大匹配数=|P|-0=|P|;即P的最小路径覆盖数为|P|;
P'中不在于匹配边时,路径覆盖数为|P|;
如果在P'中增加一条匹配边pi'-->pj'',那么在图P的路径覆盖中就存在一条由pi连接pj的边,也就是说pi与pj 在一条路径上,于是路径覆盖数就可以减少一个;
如此继续增加匹配边,每增加一条,路径覆盖数就减少一条;直到匹配边不能继续增加时,路径覆盖数也不能再减少了,此时就有了前面的公式;但是这里只 是说明了每条匹配边对应于路径覆盖中的一条路径上的一条连接两个点之间的有向边;下面来说明一个路径覆盖中的每条连接两个顶点之间的有向边对应于一条匹配 边;
与前面类似,对于路径覆盖中的每条连接两个顶点之间的每条有向边pi--->pj,我们可以在匹配图中对应做一条连接pi'与pj''的边, 显然这样做出来图的是一个匹配图(这一点用反证法很容易证明,如果得到的图不是一个匹配图,那么这个图中必定存在这样两条边 pi'---pj'' 及 pi' ----pk'',(j!=k),那么在路径覆盖图中就存在了两条边pi-->pj, pi--->pk ,那边从pi出发的路径就不止一条了,这与路径覆盖图是矛盾的;还有另外一种情况就是存在pi'---pj'',pk'---pj'',这种情况也类似可证);
至此,就说明了匹配边与路径覆盖图中连接两顶点之间边的一一对应关系,那么也就说明了前面的公式成立!
我们根据上面概念方法来画图....
让交叉点和交叉点点去匹配
那么图中连线的意思就是:1号有一条路可以去3号,二号也有一条路去3号,三号有一条路去4号,可以想象1号2号我们可以来一个伞兵任意选一个走到3号...(一个匹配),然后从3号走到4号,就先1/2---->3------>4两个匹配就走了三个点,剩下一个点就再来一个兵就可以啦。。。。那么
最小边覆盖=|P|-最大匹配这个公式就比较明了啦....

上马,马上来点解释:
  1. // 0MS 244K
  2. #include<stdio.h>
  3. #include<string.h>
  4.  
  5. #define MAX 121
  6.  
  7. int no_in,no_st;//交叉路的数量,街道数量
  8. bool map[MAX][MAX];//map[i][j]表示i号交叉口有一条街道可以达到j号交叉口
  9. int link[MAX];
  10. bool useif[MAX];
  11.  
  12. bool dfs(int t)
  13. {
  14. for(int i=1;i<=no_in;i++)
  15. {
  16. if(!useif[i] && map[t][i])
  17. {
  18. useif[i]=true;
  19. if(link[i]==-1 || dfs(link[i]))
  20. {
  21. link[i]=t;return true;
  22. }
  23. }
  24. }
  25. return false;
  26. }
  27.  
  28. int match()
  29. {
  30. int sum=0;
  31. memset(link,-1,sizeof(link));
  32. for(int i=1;i<=no_in;i++)
  33. {
  34. memset(useif,false,sizeof(useif));
  35. if(dfs(i))
  36. sum++;
  37. }
  38. return sum;
  39. }
  40.  
  41. int main()
  42. {
  43. int T;
  44. int a,b;
  45. scanf("%d",&T);
  46. while(T--)
  47. {
  48. memset(map,0,sizeof(map));
  49. scanf("%d%d",&no_in,&no_st);
  50. for(int i=1;i<=no_st;i++)
  51. {
  52. scanf("%d%d",&a,&b);
  53. map[a][b]=1;//注意是单项路
  54. }
  55. printf("%d\n",no_in-match());
  56. }
  57. return 0;
  58. }

个人愚昧观点...欢迎指正、交流讨论

[置顶] 白话最小边覆盖总结--附加 hdu1151结题报告的更多相关文章

  1. [置顶] 白话二分匹配之最大匹配+附上hdu2063解题报告

    最近开始学习图论的二分匹配,关于最大匹配做一次小总结,希望自己后面回头来看一目明了,也对刚接触的人有帮助: ps:开始有的文字很多....对于很多人来说一看到文字就烦啦...不过这个总结是针对匈牙利算 ...

  2. win8.1系统下,点击一个窗口,【当前活动窗口】该窗口无法置顶

    两个或多个窗口同时显示在桌面的时候,点击下一层的窗口,无法置顶显示,无论怎么点击,还是隐藏在原置顶窗口的后面,只能手动把原置顶窗口最小化后,才能看到.例如,A窗口现在置顶,B窗口在A的后面,露出来一部 ...

  3. wpf 窗口最小化后,触发某事件弹出最小化窗口并置顶

    //如果窗口最小化了弹出并置顶----事件触发调用 ShowWindowAsync(new System.Windows.Interop.WindowInteropHelper(CommonHelpe ...

  4. Qt 窗口操作函数(置顶、全屏,最大化最小化按钮设置等)

    一.窗口置顶 与 取消置顶 void MainWindow::on_windowTopButton_clicked() { if (m_flags == NULL) { m_flags = windo ...

  5. HDU1151:Air Raid(最小边覆盖)

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

  6. 将窗口置顶的方法:SetWindowPos、AttachThreadInput、SwitchToThisWindow

    将窗口置顶的方法:SetWindowPos.AttachThreadInput.SwitchToThisWindow [转]http://hi.baidu.com/neil_danky/item/f9 ...

  7. [Winform]检测exe是否已经运行,并将其置顶

    摘要 在很多pc应用中,基本上都需要有这样的判断,保证在一个终端只运行一个winform的client.并且如果最小化了,用户再次双击桌面图标的时候,将client置顶显示. 解决方案 需要使用win ...

  8. PKU 3020 Antenna Placement(拆点+最小边覆盖)(最大匹配)

    题目大意:原题链接 一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市.问至少放置多少个基站才能使得所有的城市都覆盖无线? 提示:看清楚题目,' ...

  9. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

随机推荐

  1. Linux 多网卡的7种bond模式原理

    Linux 多网卡绑定 网卡绑定mode共有七种(0~6) bond0.bond1.bond2.bond3.bond4.bond5.bond6 常用的有三种 mode=0:平衡负载模式,有自动备援,但 ...

  2. ASP.NET-FineUI开发实践-10

    嵌套Grid,光棍月大放送,不藏着掖着.实在写的不好,没脸藏啊~只考虑显示排序修改什么的都不管! 话说三石官网加实例了,http://fineui.com/demo/#/demo/grid/grid_ ...

  3. MVC4建立DBContext的EF6数据

    MVC4建立DBContext的EF6数据时 1.需要using System.Data.Entity;命名空间 2.此命名空间需要安装EntityFromwork.dll,此dll可以在项目——&g ...

  4. JavaScript Arguments 实现可变参数的函数,以及函数的递归调用

    //可变参数的函数 注:也可以使用对象作为参数来实现 function Max() { var temp = arguments[0] || 0; for (var i = 1; i < arg ...

  5. php学习之路

    1.php拼接字符串+查询 $floor_id = M('house_floor_input')->where($map1)->field('id')->select(); $flo ...

  6. Spring Boot Web项目之参数绑定

    一.@RequestParam 这个注解用来绑定单个请求数据,既可以是url中的参数,也可以是表单提交的参数和上传的文件 它有三个属性,value用于设置参数名,defaultValue用于对参数设置 ...

  7. c++中 cin、cin.get()、cin.getline()、cin.getchar()的区别

    ①cin>>:无法接收空格.Tap键且以空格.Tap键.回车符为分隔符: ②cin.get( ):可以接收空格.Tap键且以回车符为结束符: 一:可输入单个字符 格式: char ch; ...

  8. Java学习笔记——SequenceInputStream类合并文件的综合举例分析

    SequenceInputStream 介绍 SequenceInputStream 类表示其他输入流的逻辑串联,即文件的合并. 它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾, ...

  9. HTML5 canvas 绘制五星红旗

    这个例子并不是自己写的,在网上找的案列,仿照写的,,,自己真的公布董这些算法,看完这个例子还是有一点模糊,,, 如果谁看的比较明白,指点一下,,,多谢!!!! <!doctype html> ...

  10. 史上最全的css hack

    <!DOCTYPE html> <html> <head> <title>Css Hack</title> <style> #t ...