您的位置:首页 > 其它

lightoj1150 - Ghosts!

2016-02-03 22:20 183 查看
先预处理出来每个ghost到每个human后杀掉他后返回窝的最少时间。

然后人份时间上限建图,二分匹配判断匹配数目是否等于human的数目。。。

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2015
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 30;

int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};

vector<ii> G[N*N];

char g

;
int n;
int A

, B

;
int uN, vN;
void input() {
scanf("%d",&n);
uN = vN = 0;
memset(A, 0,sizeof A);
memset(B, 0,sizeof B);
for (int i = 1;i <= n;++i) {
scanf("%s", g[i] + 1);
for (int j = 1;j <= n;++j) {
if (g[i][j] == 'G') {
A[i][j] = ++uN;
}
if (g[i][j] == 'H') {
B[i][j] = ++vN;
}
}
}
}
bool vis

;
int dis

;
bool check(int x,int y) {
if (vis[x][y]) return false;
if (x < 1 || x > n || y < 1 || y > n || g[x][y] == '#') return false;
return true;
}
void bfs(int x,int y) {
memset(vis, false,sizeof vis);
memset(dis, -1,sizeof dis);
dis[x][y] = 0;
vis[x][y] = true;
queue<ii> que;
que.push(ii(x, y));
while(!que.empty()) {
ii tmp = que.front();
que.pop();
for (int i = 0;i < 4;++i) {
int nx = tmp.first + dx[i];
int ny = tmp.second + dy[i];
if (check(nx,ny)) {
dis[nx][ny] = dis[tmp.first][tmp.second] + 1;
que.push(ii(nx,ny));
vis[nx][ny] = true;
if (g[nx][ny] == 'H') {
G[A[x][y]].push_back(ii(B[nx][ny], dis[nx][ny] * 2 + 2));
}
}
}
}
}
void Initation() {
for (int i = 1;i <= uN;++i)
G[i].clear();
for (int i = 1;i <= n;++i) {
for (int j = 1;j <= n;++j) {
if (g[i][j] == 'G') bfs(i, j);
}
}
}

vector<int> mp[N*N];
void getmap(int x) {
for (int i = 1;i <= uN;++i) {
mp[i].clear();
for (int j = 0;j < G[i].size();++j) {
if (G[i][j].second <= x) mp[i].push_back(G[i][j].first);
}
}
}
int linker[N*N];
bool mark[N*N];
bool search(int u) {
for (int i = 0;i < mp[u].size();++i) {
int v = mp[u][i];
if (mark[v]) continue;
mark[v] = true;
if (linker[v] == -1 || search(linker[v])) {
linker[v] = u;
return true;
}
}
return false;
}
int hungary() {
int ans = 0;
memset(linker, -1,sizeof linker);
for (int i = 1;i <= uN;++i) {
memset(mark, false,sizeof mark);
if (search(i)) ans++;
}
return ans;
}
int binary() {
int ans = -1;
int low = 1, high = 100000;
while(low <= high) {
int mid = (low + high) / 2;
getmap(mid);
int tmp = hungary();
if (tmp == vN) {
ans = mid;
high = mid - 1;
}else low = mid + 1;
}
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out1.txt","w",stdout);
int t, icase = 0;
scanf("%d",&t);
while(t--) {
input();
Initation();
int ans = binary();
printf("Case %d: ", ++icase);
if (ans == -1)  puts("Vuter Dol Kupokat");
else printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: