题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26864

思路:首先是spfa预处理出每个'G'到'H'的最短距离,然后就是二分最大距离,最大匹配验证即可。

PS:这道题一开始没什么思路,然后想先最简单的spfa预处理写一下吧,然后写着写着就突然豁然开朗,有思路了!然后就AC了!

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define MAXN 55
#define inf 1<<30
#define FILL(a,b) memset(a,b,sizeof(a)) vector<pair<int,int> >g,h; int n,dir[][]={{-,},{,},{,-},{,}};
int dist[MAXN][MAXN],dd[MAXN][MAXN];
bool mark[MAXN][MAXN];
char map[MAXN][MAXN]; void spfa(int vs)
{
FILL(mark,false);
for(int i=;i<MAXN;i++)
for(int j=;j<MAXN;j++)dd[i][j]=inf;
queue<pair<int,int> >que;
que.push(make_pair(g[vs].first,g[vs].second));
dd[g[vs].first][g[vs].second]=;
while(!que.empty()){
pair<int,int>p=que.front();
que.pop();
mark[p.first][p.second]=false;
for(int i=;i<;i++){
int x=p.first+dir[i][],y=p.second+dir[i][];
if(x>=&&x<n&&y>=&&y<n&&map[x][y]!='#'){
if(dd[p.first][p.second]+<dd[x][y]){
dd[x][y]=dd[p.first][p.second]+;
if(!mark[x][y]){
mark[x][y]=true;
que.push(make_pair(x,y));
}
}
}
}
}
} vector<int>gg[MAXN];
void Build(int limit)
{
for(int i=;i<MAXN;i++)gg[i].clear();
for(int i=;i<g.size();i++){
for(int j=;j<h.size();j++){
if(dist[i][j]<=limit)gg[i].push_back(j);
}
}
} int ly[MAXN];
bool vis[MAXN]; int dfs(int u)
{
for(int i=;i<gg[u].size();i++){
int v=gg[u][i];
if(!vis[v]){
vis[v]=true;
if(ly[v]==-||dfs(ly[v])){
ly[v]=u;
return ;
}
}
}
return ;
} int MaxMatch()
{
int res=;
FILL(ly,-);
for(int i=;i<g.size();i++){
FILL(vis,false);
res+=dfs(i);
}
return res;
} int main()
{
int _case,t=;
scanf("%d",&_case);
while(_case--){
scanf("%d",&n);
g.clear();
h.clear();
for(int i=;i<n;i++)scanf("%s",map[i]);
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(map[i][j]=='G')g.push_back(make_pair(i,j));
else if(map[i][j]=='H')h.push_back(make_pair(i,j));
}
}
for(int i=;i<MAXN;i++)
for(int j=;j<MAXN;j++)dist[i][j]=inf;
for(int i=;i<g.size();i++){
spfa(i);
for(int j=;j<h.size();j++){
if(dd[h[j].first][h[j].second]!=inf)dist[i][j]=min(dist[i][j],*dd[h[j].first][h[j].second]+);
}
}
int low=inf,high=,mid,ans=inf;
for(int i=;i<g.size();i++){
for(int j=;j<h.size();j++){
if(dist[i][j]!=inf){
low=min(low,dist[i][j]);
high=max(high,dist[i][j]);
}
}
}
while(low<=high){
mid=(low+high)>>;
Build(mid);
if(MaxMatch()==(int)h.size()){
ans=mid;
high=mid-;
}else
low=mid+;
}
printf("Case %d: ",t++);
if(ans!=inf){
printf("%d\n",ans);
}else
puts("Vuter Dol Kupokat");
}
return ;
}

loj 1150(spfa预处理+二分+最大匹配)的更多相关文章

  1. loj 1316(spfa预处理+状压dp)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27024 题意:求0-(n-1)的经过最多的标记的点的最短路. 思路 ...

  2. hdu 4568 Hunter(spfa预处理 + 状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4568 思路:首先spfa预处理出每对宝藏之间的最短距离以及宝藏到边界的最短距离,然后dp[state] ...

  3. hdu2063 匈牙利算法 二分最大匹配模版题

    过山车 Time Limit: 1000 MS Memory Limit: 32768 KB 64-bit integer IO format: %I64d , %I64u Java class na ...

  4. POJ 3041 Asteroids(模板——二分最大匹配(BFS增广))

    题目链接: http://poj.org/problem?id=3041 Description Bessie wants to navigate her spaceship through a da ...

  5. hdu 4568(SPFA预处理+TSP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4568 思路:先用spfa预处理出宝藏与宝藏之间的最短距离,宝藏到边界的最短距离,然后就是经典的求TSP ...

  6. hdu 2444 交叉染色判断二分图+二分最大匹配

    /*1A 31ms*/ #include<stdio.h> #include<string.h> #define N 300 int n; struct node { int ...

  7. [codeforces 852 D] Exploration Plan 解题报告 (二分+最大匹配)

    题目链接:http://codeforces.com/problemset/problem/852/D 题目大意: 有V个点,N个队伍,E条边,经过每条边有个时间,告诉你初始N个队伍的位置,求至少有K ...

  8. UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)

    题意: 给定一个n个点m条边的带权有向图,求平均权值最小的回路的平均权值? 思路: 首先,图中得有环的存在才有解,其次再解决这个最小平均权值为多少.一般这种就是二分猜平均权值了,因为环在哪也难以找出来 ...

  9. poj 3501 Escape from Enemy Territory 预处理+二分+bfs

    传送门 给一个起点一个终点, 给出整个地图的宽和高, 给出n个敌人的坐标. 让你找到一条路径, 这条路径上的点距离所有敌人的距离都最短, 输出最短距离. 首先预处理出来地图上的所有点到敌人的最短距离, ...

随机推荐

  1. ThinkPHP3.2.3自带的分页用法--很简单实用

    把解压后的Page.class.php放入ThinkPHP/Extend/Library/ORG/Util/(如果没有请手动创建)目录下面.thinkphp 自带的分页非常好用美观,先看一下如下代码片 ...

  2. codevs1688 求逆序对

    题目描述 Description 给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目 数据范围:N<=105.Ai<=105. ...

  3. iOS开发——底层OC篇&运行时常用

    运行时常用 什么是Runtime(前面的文章已经说的很清楚了,这里就简单的介绍一下) 我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,例如[target doSomething]; ...

  4. [HDU5015]233 Matrix

    [HDU5015]233 Matrix 试题描述 In our daily life we often use 233 to express our feelings. Actually, we ma ...

  5. C#装箱和拆箱(值类型和引用类型之间的转换)

    面向对象编程中,封箱指把非对象类型的数值或数据,包装成对象类型反之,拆箱指把对象类型拆成非对象的数值或数据. 例子:定义一个Circle 类 class Circle { double radius; ...

  6. poj1182(食物链)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 49320   Accepted: 14385 Description ...

  7. 使用Discuz关键词服务器实现PHP中文分词

    不同于使用自己的服务器进行分词,Discuz!在线中文分词服务是基于API返回分词结果的.在项目中,我们只需要一个函数即可方便地进行分词.关键词提取.以下是根据Discuz!在线分词服务API写的函数 ...

  8. 学习jquery mobile

    学习jquery mobile的时间不是很长,在学习的过程当中也遇到了很多令人抓狂的问题,在网上搜索问题答案的时候发现,现在关于jquery mobile的文章还不是很多,所以,我也是一边学习,一边摸 ...

  9. tmux简单使用指南

    一, ubuntu安装tmux sudo apt-get install tmux 二, tmux使用 1)打开shell,输入命令tmux,,shell下边会出现绿色状态条 2)然后同时按下ctrl ...

  10. string s = null 和 string s = “”的区别

    string s = null; 表示一个空串,没有占用了空间,不在内存中开辟空间 string s = "";在内存中开辟空间,但空间中没有值(""也是一个字 ...