https://vjudge.net/problem/UVA-11419 题意:一个网格里面有一些目标,可以从某一行,某一列发射一发子弹,可以打掉它:求最少的子弹,和在哪里打? 思路: 每个点的x坐标与y坐标相连,现在就是要找一个最小点覆盖,同时还要输出哪些点被覆盖了. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std…
题目链接:https://vjudge.net/problem/UVA-11419 题意:一个网格里面有一些目标,可以从某一行,某一列发射一发子弹,可以打穿: 求最少的子弹,和在哪里打? 分析: 听说可以用吗MCMF做,没多想: 一个目标,拆成两个点,X,Y,X与Y之间连一条边,现在,在这些点里面选出一些点,使得每一条边都有一个端点被覆盖,这就是最小点覆盖=最大匹配(证明在之前写过,博客里可以找到,证明很有意思): 然后还要找出哪些被覆盖了: #include <cstdio> #includ…
layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 最小点覆盖 - 图论 - 训练指南 SAM I AM UVA - 11419 题目大意:给出一个R×C的网格,网格上棉纺了一些目标.可以在网格外发射子弹,子弹会沿着垂直或水平方向飞行,并且打掉飞行路径上的所有目标.你的任务是计算出最少需要多少子弹,各从哪个位置发射,才…
用到了二分图的一些性质, 最大匹配数=最小点覆盖 貌似在白书上有讲 还不是很懂, 自己看着别人的博客用网络流写了一遍 反正以后学白书应该会系统学二分图的,紫书上没讲深. 目前就这样吧. #include<cstdio> #include<vector> #include<cstring> #include<queue> #include<algorithm> #define REP(i, a, b) for(int i = (a); i <…
/** 题目:SAM I AM UVA - 11419 链接:https://vjudge.net/problem/UVA-11419 题意:给定n*n的矩阵,'X'表示障碍物,'.'表示空格;你有一把枪,每一发子弹可以消除一行或者一列的障碍物, 问最少需要多少颗子弹可以清空障碍物?以及输出具体的哪些行,哪些列. 思路:最小点集覆盖问题,等价于最大匹配. 求具体的哪些行,哪些列,需要借助于匈牙利树.从X中所有未匹配的点出发扩展匈牙利树,标记 树中的所有点,则X中所有的未标记点和Y中的所有标记点就…
题意:在方格图上打小怪,每次可以清除一整行或一整列的小怪,问最少的步数是多少,又应该在哪些位置操作(对输出顺序没有要求). 分析:最小覆盖问题 这是一种在方格图上建立的模型:令S集表示“行”,T集表示“列”,那么小怪站的位置w(i,j),就是二分图上的边.如此建图,那么每次清除,就是把与某个点相连的边全部清除,问最少选择多少个点.(这也是最小点覆盖的概念:选择尽量少的点,使得每条边至少有一个端点被选中) 这里有一个König定理:最大二分匹配数==最小覆盖点数. 既然是求最小点覆盖,那么自然是选…
题意:给一个r*c的矩阵,某些格子中可能有一些怪物,可以在一行或一列防止一枚大炮,大炮会扫光整行/列的怪,问最少需要多少炮?输出炮的位置. 思路: 先每行和列都放一个炮,把炮当成点,把怪当成边,一边连接行炮,另一边是列炮,只要其中任何一个扫了,另一个就不必了.所以明显是求最小点覆盖,用最少的点(即炮)覆盖最多的边(即怪).进而转成最大匹配.因 最大匹配数=最小覆盖数. 这题还得求炮的位置,也就是覆盖点集.可以根据匈牙利数来构造,而且可以用同匈牙利算法那个DFS函数,稍微加点东西而已.神奇之处在于…
题目链接:https://vjudge.net/problem/UVA-11419 题解: 1.二分图匹配之最小点覆盖.:把x坐标和y坐标看成是点, 图中的目标看成是边,所以最终的目的是求出用最少的点,去覆盖掉所有的边.如果在M[x][y]处有目标,则连一条边x-y.接着跑一遍匈牙利算法. 2.除此之外,题目还要求输出最小覆盖点集.可知我们已经求出了最大匹配数,首先我们把所有的覆盖点都落在左边的匹配点上.但是这样做却不能保证所有的边都会被覆盖,因为假设左边有未匹配点,且这些未匹配点与右边的点(是…
题目大意:在一个n*m的网格中,有k个目标,现在可以任选一行或列消除在其上的所有目标,求出最少选择次数及选法. 题目分析:经典的最小点覆盖问题,并且输出一个最小点覆盖集.在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # incl…
题意:最小路径覆盖 题解:对于一个有向图,最小点覆盖 = 顶点数 - 最大匹配 这里的最大匹配指的是将原图中每一个点拆成入点.出点, 每条边连接起点的出点和终点的入点 源点S连接每个点的出点,汇点T连接每个点的入点,这样建出来的二分图的最大匹配 然后输出路径被坑了很久 因为自己拆点的标号问题吧 我的拆点方式入点是偶数 出点是奇数 然后特判哪里就要写清楚 #include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3…