poj 3020 Antenna Placement (最小路径覆盖, 匈牙利算法, 拆点形成二分图)
来源:互联网 发布:数据采集仪销售电话 编辑:程序博客网 时间:2024/05/16 03:56
题意: 给出网格, 每个点有两种可能: 空地或者城市. 现在要建立无线网络区, 每个无线网络区只能放在城市中, 并且只能朝东南西北某一个方向覆盖另外一个城市(必须相邻), 求最少要建立几个无线网络区才能覆盖所有的城市.
分析: 如果把每个无线网络所在城市与其覆盖的另一个城市之间视作一条路径的话, 那么所有的城市都只能属于其中一条路径, 所以题目可以理解为, 存在多少条路径可以覆盖掉所有的城市, 即最小路径覆盖数. 又 最小路径覆盖数 = 总点数|P| - 最大匹配数. 所以可以通过将所有城市之间的相邻关系建立成一张图, 再求最大匹配数(可采用匈牙利算法).
建图: 题目给的是以(*,o)组成的网格.可以将*所在位置以数字进行编号, 如
oo**oo
*o*oo*
***o*o
可编号为:
001200
304005
678090
由于每个点都可能作为无线网络区去对相邻点覆盖即存在1->2和2->1的情况, 说明该图可为无向图.
要求最大匹配数就得将图拆成二分图. 我们可以采用拆点的方法, 即一个点拆成两个点, 分别置于V集合和V'集合,这样就可以形成二分图, 点集两边点数相等.
(注意:此时求出的最大匹配数为原图的2倍, 原因是: 假如V集中点1与V'集中点2'相匹配, 则由于拆点的关系, 必定存在V集中点2与V'集中点1'相匹配.故最后计算的时候应该除以2).
最小路径覆盖数 = 总点数|P|- 最大匹配数 . 证明参考百度百科: 最小路径覆盖公式证明
#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<stack>#include<cstdio>using namespace std;int n, m, len, ans;int Map[550][550];int edge[550][550];int d[4][2]={{-1, 0}, {0,-1}, {1, 0}, {0, 1}};int flag[550], link[550];bool dfs(int x){int y;for(y=1; y<=len; y++){if(edge[x][y] && !flag[y]){flag[y]=1;if(link[y]==0 || dfs(link[y])){link[y] = x;return true;}}}return false;}int main(){int T, i, j, k;scanf("%d", &T);while(T--){//注意初始化memset(link, 0, sizeof(link));memset(Map, 0, sizeof(Map));memset(edge, 0, sizeof(edge));scanf("%d %d%*c", &n, &m);char c;len=0;for(i=1; i<=n; i++){for(j=1; j<=m; j++){scanf("%c", &c);if(c=='*'){Map[i][j] = ++len;//给每个城市编号, Map存每个城市的编号}}getchar();}//建图 -> 拆点int x, y;for(i=1; i<=n; i++){for(j=1; j<=m; j++){if(Map[i][j]){int id = Map[i][j];for(k=0; k<4; k++){//东南西北连边中~~~x = i+d[k][0];y = j+d[k][1];int idd = Map[x][y];if(Map[x][y]) edge[id][idd]=1;}}}}ans=0;for(i=1;i<=len; i++){memset(flag, 0, sizeof(flag));if(dfs(i)) ans++;}//len是总点数, ans是上图求出的最大匹配数, 应当除以2才是原集合的最大匹配数printf("%d\n", len-ans/2);}return 0;}
0 0
- poj 3020 Antenna Placement (最小路径覆盖, 匈牙利算法, 拆点形成二分图)
- poj 3020 Antenna Placement(最小路径覆盖 + 匈牙利算法)
- POJ 3020 Antenna Placement(匈牙利算法—最小路径覆盖)
- 【二分图+最小路径覆盖】北大 poj 3020 Antenna Placement
- poj 3020 Antenna Placement 二分图最小路径覆盖
- POJ 3020 Antenna Placement ,二分图的最小路径覆盖
- POJ - 3020 Antenna Placement 二分图 最小路径覆盖
- Poj 3020 Antenna Placement (二分图最小路径覆盖)
- POJ 3020 Antenna Placement(二分图最小路径覆盖)
- [POJ 3020]Antenna Placement[二分图最小路径覆盖]
- poj 3020 Antenna Placement 匈牙利二分匹配 最小覆盖数 !!!!
- Poj 3020 Antenna Placement【最小边覆盖 匈牙利算法】
- POJ 3020 Antenna Placement(二分图建图训练 + 最小路径覆盖)
- POJ-3020-Antenna Placement [二分匹配][最小路径覆盖]
- poj 3020 Antenna Placement (最小路径覆盖)
- POJ 3020 Antenna Placement (最小路径覆盖)
- POJ 3020:Antenna Placement(最小路径覆盖)
- POJ-3020 Antenna Placement(最小点覆盖)
- qw
- 美团点评面试有感
- linux下使用 du查看某个文件或目录占用磁盘空间的大小
- tar安装程序&配置java变量
- js和java当前系统时间
- poj 3020 Antenna Placement (最小路径覆盖, 匈牙利算法, 拆点形成二分图)
- 让Linux系统允许使用root账号远程登录
- 进击的eclipse--配置一个好用的eclipse
- 第三周:具体命令的学习
- AndroidStudio利用android-support-multidex解决65536问题64k问题
- Python获取数据库数据并保存在excel表格中
- hibernate catalog 坑
- nmap学习之操作系统探测
- socket的发送与接收缓冲区