首页 > 代码库 > poj 3020 Antenna Placement 解题报告
poj 3020 Antenna Placement 解题报告
题目链接:http://poj.org/problem?id=3020
题目意思:首先,请忽略那幅有可能误导他人成分的截图(可能我悟性差,反正有一点点误导我了)。
给出一幅 h * w 的图, “ * ” 表示 point of interest,“ o ” 忽略之。你可以对 " * " (假设这个 “* ”的坐标是 (i, j))画圈,每个圈只能把它四周的某一个点括住(或者是上面(i-1, j) or 下面(i+1, j) or 左边(i, j-1) or 右边(i, j+1)),也就是说,这个圈 只能覆盖两个 “ * ” 点。问最少需要多少个这样的圈 来括住所有的 " * "。
这题实质上求得是无向二分图的最小路径覆盖数,最关键的是建图!!!!
还有就是需要知道一个公式:无向二分图的最小路径覆盖 = 顶点数 – 最大二分匹配数/2
参考了别人的建图方式,真是太强大了~~~~
建图如下:每遇到一个 " * " 就记录这个 " * " 的编号,就好像7 9 这幅图的第二行,它的 " * " 依次的编号是3 4 5 6,因为第一行的 “ *” 已经把编号1, 2用了,实质代表这个 " * " 是第 几 个 point of interest。接着对每个 " * " (假设编号为 i )遍历它的四个方向,如果它的某个方向也有 " * " (编号为 j), 那么就将 i 和 j 连边。
最后匈牙利模板求匹配数,至于总的编号数就是公式中的顶点数,套入公式,大功告成也 ^_^........
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 500 + 10; 7 8 int vis[maxn], match[maxn]; 9 int map[maxn][maxn], mark[maxn][maxn];10 int cnt, maxmatch; // cnt: 顶点数 maxmatch:最大匹配数11 12 int dx[] = {0, 0, 1, -1};13 int dy[] = {1, -1, 0, 0};14 15 int dfs(int x)16 {17 for (int i = 1; i <= cnt-1; i++)18 {19 if (!vis[i] && map[x][i])20 {21 vis[i] = 1;22 if (!match[i] || dfs(match[i]))23 {24 match[i] = x;25 return 1;26 }27 }28 }29 return 0;30 }31 32 void Hungary()33 {34 maxmatch = 0;35 for (int i = 1; i <= cnt-1; i++)36 {37 memset(vis, 0, sizeof(vis));38 maxmatch += dfs(i);39 }40 }41 42 int main()43 {44 int T, h, w;45 while (scanf("%d", &T) != EOF)46 {47 while (T--)48 {49 scanf("%d%d", &h, &w);50 char ch;51 cnt = 1;52 memset(mark, 0, sizeof(mark));53 memset(map, 0, sizeof(map));54 memset(match, 0, sizeof(match));55 56 for (int i = 0; i < h; i++)57 {58 for (int j = 0; j < w; j++)59 {60 cin >> ch;61 if (ch == ‘*‘)62 {63 mark[i][j] = cnt;64 cnt++;65 }66 }67 }68 for (int i = 0; i < h; i++)69 {70 for (int j = 0; j < w; j++)71 {72 if (mark[i][j])73 {74 int tmp = mark[i][j]; // 当前"*"编号75 for (int k = 0; k < 4; k++) // 遍历它的四个方向76 {77 int ti = i + dx[k];78 int tj = j + dy[k];79 if (ti >= 0 && ti < 40 && tj >= 0 && tj < 10 && mark[ti][tj] > 0)80 map[tmp][mark[ti][tj]] = 1;81 }82 }83 }84 }85 }86 Hungary();87 printf("%d\n", cnt-1-maxmatch/2);88 }89 }90 return 0;91 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。