poj 3041
来源:互联网 发布:恐怖故事2剧情解析知乎 编辑:程序博客网 时间:2024/06/17 07:50
//相关知识点
¥ 最小覆盖: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数 M
¥ 简单的证明如下:
¥ (1)M个是足够的。只需要让它们覆盖最大匹配的M条边,则其它边一定被覆盖(如果有边e不被覆盖,把e加入后得到一个更大的匹配)
¥ (2)M个是必需的,仅考虑形成最大匹配的这M条边,由于它们两两之间没有公共点,因此至少需要M个点才可以把它们覆盖
对于这题 那个数据我们可以用下面的表示,0表示无障碍物,1表示有;
1 0 1
0 1 0
0 1 0
首先,我们利用行跟列做二分图:
如果第i行的第j列有障碍物,则在图中左边的i行连一条边到右边的j列,上面的数据
于是问题就转化成最小点覆盖的问题.求最大匹配即可.
Code:
#include<iostream>using namespace std; bool map[502][502];int linkx[502],linky[502];//linkx表示x所对应的y,linky表示y所对应的xbool used[502]; int n; int path(int x){ for(inti=1;i<=n;i++)//y轴遍历 { if(!used[i]&&map[x][i]) { used[i]=true;//别忘咯 if(linky[i]==-1||path(linky[i])) { linky[i]=x; linkx[x]=i; return1; } } } return0;} int main(){ intk,num,a,b,i; while(scanf("%d%d",&n,&k)!=EOF) { memset(map,false,sizeof(map)); while(k--) { scanf("%d%d",&a,&b); map[a][b]=true; } num=0; memset(linkx,0xff,sizeof(linkx)); memset(linky,0xff,sizeof(linky)); for(i=1;i<=n;i++)//x轴 { if(linkx[i]==-1)//x轴不存在路径 { memset(used,false,sizeof(used)); num+=path(i);// } } printf("%d\n",num); } return0;}
- POJ 3041 POJ 3041
- POJ 3041
- poj 3041
- POJ 3041
- poj.3041
- poj-3041
- poj 3041
- poj 3041
- poj 3041
- poj 3041
- POJ 3041
- poj 3041
- POJ-3041
- 【POJ】3041
- POJ 3041 Asteroids
- poj 3041 Asteroids
- poj 3041 匈牙利算法
- poj 3041(匈牙利)
- 读超级整理书
- 北大青鸟给了你什么?
- C++类库介绍
- java第五周(矩阵中数据的位置变换功能、矩阵的加法功能、矩阵的乘法功能)
- 设计模式之十六------Observer(观察者)
- poj 3041
- javaweb之renponse验证码及刷新、重定向
- ubuntu 12.10 安装oracle10g
- 正则表达式快速入门
- IOCP服务器模型
- Linux下C线程池的实现
- POJ 3628 - Bookshelf 2
- TinyXml快速入门2
- API库函数调用与随机数生成