poj 3041 Asteroids 最大匹配
2016-04-19 11:56
323 查看
把每一列当成一个点,每一行当成一个点,若行节点和列节点之间有边,则表明该行列该列有一个障碍物。
可以放炸弹炸掉成行或者成列的障碍物!
主要是构图:将每一行当成一个点,构成集合1, 每一列也当成一个点,构成集合2;每一个障碍物的位置坐标将集合1与集合2中的点连接起来,也就是将每一个障碍物作为连接节点的边。这样可以轻易的得出本题是一个最小点覆盖的问题,假设1个行节点覆盖了5个列节点,即这个行节点与这5个列节点间有5条边(即五个障碍物),由于这5条边都被那个行节点覆盖,即表明这5个障碍物都在同一列上,于是可以一颗炸弹全部清除,而本题也就转化成求最小点覆盖数的问题。
又有一个定理是:最小点覆盖数 = 最大匹配数, 所以此题转化成求最大匹配数。
最大匹配算法又称匈牙利算法
//思路:将行看做U集合,列看做V集合,进行增广路的寻找
#include<stdio.h>
#include<string.h>
#define max 10002
int map[502][502];
bool visit[max];
int match[max];
int n;
int path(int start)
{
int i,j;
for(i=1;i<=n;i++) //找从U的某个点与V集合的有关系的点
{
if(visit[i]==false && map[start][i]==1)
{
visit[i]=1; //如果以U的第一个点开始的V的点跟start有关系的话,那么记录
if(match[i]==-1 || path(match[i])) //如果找到的点已经找到匹配的话,那么继续找
{
match[i]=start;
return true;
}
}
}
return false;
}
int main()
{
int m;
scanf("%d%d",&n,&m);
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
int i,j;
int a,b;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=1; //有向图
}
int result=0;
for(i=1;i<=n;i++) //从U集合的第一个数字寻找
{
memset(visit,false,sizeof(visit));
if(path(i))
result++;
}
printf("%d\n",result);
return 0;
}
可以放炸弹炸掉成行或者成列的障碍物!
主要是构图:将每一行当成一个点,构成集合1, 每一列也当成一个点,构成集合2;每一个障碍物的位置坐标将集合1与集合2中的点连接起来,也就是将每一个障碍物作为连接节点的边。这样可以轻易的得出本题是一个最小点覆盖的问题,假设1个行节点覆盖了5个列节点,即这个行节点与这5个列节点间有5条边(即五个障碍物),由于这5条边都被那个行节点覆盖,即表明这5个障碍物都在同一列上,于是可以一颗炸弹全部清除,而本题也就转化成求最小点覆盖数的问题。
又有一个定理是:最小点覆盖数 = 最大匹配数, 所以此题转化成求最大匹配数。
最大匹配算法又称匈牙利算法
//思路:将行看做U集合,列看做V集合,进行增广路的寻找
#include<stdio.h>
#include<string.h>
#define max 10002
int map[502][502];
bool visit[max];
int match[max];
int n;
int path(int start)
{
int i,j;
for(i=1;i<=n;i++) //找从U的某个点与V集合的有关系的点
{
if(visit[i]==false && map[start][i]==1)
{
visit[i]=1; //如果以U的第一个点开始的V的点跟start有关系的话,那么记录
if(match[i]==-1 || path(match[i])) //如果找到的点已经找到匹配的话,那么继续找
{
match[i]=start;
return true;
}
}
}
return false;
}
int main()
{
int m;
scanf("%d%d",&n,&m);
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
int i,j;
int a,b;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=1; //有向图
}
int result=0;
for(i=1;i<=n;i++) //从U集合的第一个数字寻找
{
memset(visit,false,sizeof(visit));
if(path(i))
result++;
}
printf("%d\n",result);
return 0;
}
相关文章推荐
- log4j2 配置 基于JAVA 以Web为例
- 新编日语第四册(修订版)
- 20160419—JS备忘:服务器回发刷新页面提示重试的解决方案。
- C++访问声明
- ZOJ 3323(B)模拟
- php字符串截取函数
- 漫游Kafka实战篇之客户端编程实例
- 正則表達式常用一
- hdoj 1789 Doing Homework again
- 成都Uber优步司机奖励政策(4月19日)
- #pragma
- Mongodb启动命令mongod参数说明
- 静态代码块 构造函数 静态代码块块执行顺序
- SQL SERVER常用函数
- SwipeListView 详解 实现微信,QQ等滑动删除效果
- ZOJ 3322(A)
- 关于JNI
- 择业面对选择,嵌入式 or 互联网,该进哪个?
- Orleans chat 精华记录
- 基本的常用的注解