lightoj 1150 - Ghosts! 【BFS + 二分查找 + 判二分图完美匹配】
来源:互联网 发布:中日贸易数据 编辑:程序博客网 时间:2024/06/05 22:26
It's a dark, cloudy and spooky night. The ghosts of 'VutPara' graveyard have awakened. They are planning to take revenge against humans. They are dead but the humans are alive that's their main headache. So, they want to frighten all the people nearby.
'Vutpara' can be described as an n x n grid. Each cell can be one of the following types:
'.' - The cell is empty
'G' - The cell contains a ghost
'H' - The cell contains a human
'#' - The cell contains over-polluted air, the ghosts can't fly over this cell
The ghosts can move vertically or horizontally but not diagonally. And they can fly to any cell if the air is not over-polluted. It takes one minute to move to an adjacent cell. And it takes two minutes to frighten a human if the ghost is flying over the human (means that the position of the ghost and the human is same). But the ghosts are quite lazy, so any ghost can frighten at most one human. And after their work is done they want to go back to their grave (Initial position).
The night is getting over and they have a little time left. As they are smart enough they know all the human positions and the map. Now they want to frighten all the humans in the map using minimum time.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a blank line and an integer n (5 ≤ n ≤ 25). Then n lines follow. Each of the line contains n characters each describing 'Vutpara'. You can assume that number of ghosts is always greater than or equal to the number of humans and the number of ghosts is no more than 50. And there is at least one human in the map.
Output
For each case of input, print the case number and the minimum time needed to frighten all the people or 'Vuter Dol Kupokat' if it's not possible to frighten all the people.
Sample Input
Output for Sample Input
4
8
....##..
.....#..
..#...G.
G...####
H#..HG.G
#....#.#
H.#G..H.
..##...#
6
......
G.....
......
......
......
.....H
6
.....G
.H....
......
......
....H.
G.....
6
#.#G#.
G....#
G..##.
H###.#
...#H#
..#GHH
Case 1: 12
Case 2: 20
Case 3: 12
Case 4: Vuter Dol Kupokat
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define MAXN 60#define INF 0x3f3f3f3fusing namespace std;int dist[MAXN][MAXN][MAXN];int N, M;//幽灵数 人数struct perfectmatch{ int Map[MAXN][MAXN]; bool used[MAXN]; int match[MAXN]; int DFS(int x) { for(int i = 1; i <= N; i++) { if(Map[x][i] && !used[i]) { used[i] = true; if(match[i] == -1 || DFS(match[i])) { match[i] = x; return 1; } } } return 0; } bool judge() { int ans = 0; memset(match, -1, sizeof(match)); for(int i = 1; i <= M; i++) { memset(used, false, sizeof(used)); ans += DFS(i); } return ans == M; }}PM;int n; char str[MAXN][MAXN];struct rec{ int x, y; int step;};rec g[MAXN], h[MAXN];void getMap(){ scanf("%d", &n); N = M = 0; for(int i = 0; i < n; i++) { scanf("%s", str[i]); for(int j = 0; j < n; j++) { if(str[i][j] == 'G') g[++N].x = i, g[N].y = j; if(str[i][j] == 'H') h[++M].x = i, h[M].y = j; } }}void new_map(int mid){ memset(PM.Map, 0, sizeof(PM.Map)); for(int i = 1; i <= M; i++) for(int j = 1; j <= N; j++) if(dist[i][g[j].x][g[j].y] <= mid) PM.Map[i][j] = 1;}bool vis[MAXN][MAXN];bool Can(rec a){ return a.x >= 0 && a.x < n && a.y >= 0 && a.y < n && str[a.x][a.y] != '#' && !vis[a.x][a.y];}void BFS(int id, int sx, int sy){ memset(vis, false, sizeof(vis)); int Move[4][2] = {0,1, 0,-1, 1,0, -1,0}; queue<rec> Q; rec now, next; now.x = sx, now.y = sy, now.step = 0; Q.push(now); while(!Q.empty()) { now = Q.front(); Q.pop(); dist[id][now.x][now.y] = now.step; for(int k = 0; k < 4; k++) { next.x = now.x + Move[k][0]; next.y = now.y + Move[k][1]; if(Can(next)) { next.step = now.step + 1; vis[next.x][next.y] = true; Q.push(next); } } }}int k = 1;void solve(){ memset(dist, INF, sizeof(dist)); for(int i = 1; i <= M; i++) BFS(i, h[i].x, h[i].y); int l = 0, r = 1200, mid; int ans = INF; while(r >= l)//二分 { mid = (l + r) >> 1; new_map(mid); if(PM.judge())//完美匹配 ans = mid, r = mid - 1; else l = mid + 1; } printf("Case %d: ", k++); if(ans == INF) printf("Vuter Dol Kupokat\n"); else printf("%d\n", ans * 2 + 2);}int main(){ int t; scanf("%d", &t); while(t--) { getMap(); solve(); } return 0;}
- lightoj 1150 - Ghosts! 【BFS + 二分查找 + 判二分图完美匹配】
- LightOJ - 1150 Ghosts!(二分图+bfs+枚举)
- 二分图完美匹配模板
- 二分图最佳完美匹配
- 二分图最佳完美匹配
- 二分图最优完美匹配
- HDU 2444 黑白染色判二分图+二分最大匹配
- LightOJ _1138(二分查找)
- 二分图的最大匹配完美匹配
- lightoj 1061 KM 二分图匹配
- LightOJ 1209 - Strange Voting 【二分图匹配】
- LightOJ - 1152 Hiding Gold(二分图匹配)
- lightoj 1184 Marriage Media [二分图匹配]
- poj3057 bfs+二分匹配
- hdu 4751 Divide Groups(判完美二分图)
- HDU——2444The Accomodation of Students(BFS判二分图+最大匹配裸题)
- A 判二分图
- 【完美的牛栏】二分图匹配
- 专访百度资深工程师孙源:代码强迫症的死实践派
- android等待对话框
- PHPCMSV9文章页显示发布者
- Linux 目录结构及文件基本操作,转载自实验楼
- http://blog.csdn.net/liulina603/article/details/8617281
- lightoj 1150 - Ghosts! 【BFS + 二分查找 + 判二分图完美匹配】
- 通过点击按钮实现ViewPager的切换
- NOIP考试必备——随机数
- ubuntu 下codeblocks的相关配置
- UICollectionView
- Android-ContentProvide
- configure文件的生成
- 利用真值表法求取主析取范式以及主合取范式的实现
- 启动datanode后jps下无datanode的解决方法