参考自: http://user.qzone.qq.com/289065406/blog/1299322465

解题思路:

把方阵看做一个特殊的二分图(以行列分别作为两个顶点集V1、V2,其中| V1|=| V2|)

然后把每行x或者每列y看成一个点,而障碍物(x,y)可以看做连接x和y的边。按照这种思路构图后。问题就转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。

再利用二分图最大匹配的König定理:

最小点覆盖数 = 最大匹配数

(PS:最小点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖图的所有的边。)

因此本题自然转化为求 二分图的最大匹配 问题

 

求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的。但是这个算法的时间复杂度为边数的指数级函数

因此,需要寻求一种更加高效的算法——增广路求最大匹配的方法(匈牙利算法)

增广路的定义(也称增广轨或交错轨):

若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。

由增广路的定义可以推出下述三个结论:

 1、P的路径个数必定为奇数,第一条边和最后一条边都不属于M。

2、将M和P进行取反操作可以得到一个更大的匹配M’

(反操作:把P中的 匹配边 与 非匹配边 互换)

3、M为G的最大匹配当且仅当不存在M的增广路径P

匈牙利算法轮廓:

  (1)置M为空

  (2)找出一条增广路径P,通过异或操作获得更大的匹配M’代替M

  (3)重复(2)操作直到找不出增广路径为止

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define Del(x,y) memset(x,y,sizeof(x))
int map[][],vis[],link[];
int n,k; bool dfs(int x)
{
for(int i=;i<=n;i++)
if(map[x][i]==&&vis[i]==)
{
vis[i]=;
if(link[i]==-||dfs(link[i]))
{
link[i]=x;
return true;
}
}
return false;
} void solve()
{
int ans=;
Del(link,-);
for(int i=;i<=n;i++)
{
Del(vis,);
if(dfs(i))
ans++;
}
printf("%d\n",ans);
} int main()
{
int r,c;
scanf("%d%d",&n,&k);
Del(map,);
while(k--)
{
scanf("%d%d",&r,&c);
map[r][c]=;
}
solve();
return ;
}

POJ_3041_Asteroids的更多相关文章

随机推荐

  1. C# PDF Page操作——设置页面切换按钮 C# 添加、读取Word脚注尾注 C#为什么不能像C/C++一样的支持函数只读传参 web 给大家分享一个好玩的东西,也许你那块就用的到

    C# PDF Page操作——设置页面切换按钮   概述 在以下示例中,将介绍在PDF文档页面设置页面切换按钮的方法.示例中将页面切换按钮的添加分为了两种情况,一种是设置按钮跳转到首页.下页.上页或者 ...

  2. Raphael.js API 之Element.remove(),Element.removeData(),paper.text(),Element.node(),Element.onDragOver

    /*API-38*/ Element.remove() 删除某个元素对象,无返回值 /*API-39*/ Element.removeData([key]); 删除某个key的value值.假设没有特 ...

  3. 使用 FFmpeg 处理高质量 GIF 图片

    使用 FFmpeg 处理高质量 GIF 图片 - 为程序员服务  http://ju.outofmemory.cn/entry/169845

  4. IntelliJ IDEA 缓存和索引介绍

    转自:https://www.cnblogs.com/zhanghaibinblogs/p/6722061.html IDEA 在首次加载项目的时候都会创建索引,IDEA 的缓存和索引主要是用来加快文 ...

  5. 18. 视图Ext.Viewport和窗口Ext.Window用法

    转自:http://www.cnblogs.com/linjiqin/archive/2011/06/22/2087003.html 视图Ext.Viewport和窗口Ext.Window用法. 1. ...

  6. 浅谈C++多态性(转载)

    转载:http://blog.csdn.net/hackbuteer1/article/details/7475622 C++编程语言是一款应用广泛,支持多种程序设计的计算机编程语言.我们今天就会为大 ...

  7. 清北考前刷题day6早安

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  8. VUE中全局变量的定义和使用

    目录 VUE中全局变量的定义和使用 1.工作中遇到的两类问题 1.1 状态值(标志) 1.2 传递字段 2.解决方法 2.1 VUEX 2.2 使用全局变量法管理状态与字段值 3.具体实现 3.1创建 ...

  9. ASP.NET MVC5 之 分部页

    1.分部页 _PartialPage.cshtml @model List<string> <a>完美世界</a> @foreach (var item in Mo ...

  10. Lightoj 1020 - A Childhood Game (博弈)

    题目链接: 1020 - A Childhood Game 题目描述: Alice和Bob在玩弹珠游戏,两人轮流拿走弹珠,每次只能拿走一个或者两个,当Alice作为先手时谁拿走最后一个就是输家,而Bo ...