您的位置:首页 > 其它

洛谷P1902 刺杀大使(二分答案+bfs验证)

2017-10-21 16:06 351 查看
题目描述

伊朗伊斯兰革命卫队(某恐怖组织)正在策划一起刺杀行动,他们的目标是沙特驻美大 使朱拜尔。他们来到了沙特驻美使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前 的防御迷阵。

迷阵由 n*m 个相同的小房间组成,每个房间与相邻四个房间之间有门可通行。在第 n 行的 m 个房间里有 m 个机关,这些机关必须全部打开才可以进入大使馆。而第 1 行的 m 个 房间有 m 扇向外打开的门,是迷阵的入口。除了第 1 行和第 n 行的房间外,每个房间都被 使馆的安保人员安装了激光杀伤装置,将会对进入房间的人造成一定的伤害。第 i 行第 j 列 造成的伤害值为 p[i][j](第 1 行和第 n 行的 p 值全部为 0)。

现在伊斯兰革命卫队打算以最小伤害代价进入迷阵,打开全部机关,显然,他们可以选 择任意多的人从任意的门进入,但必须到达第 n 行的每个房间。一个士兵受到的伤害值为他 到达某个机关的路径上所有房间的伤害值中的最大值,整个部队受到的伤害值为所有士兵的 伤害值中的最大值。现在,这个恐怖组织掌握了迷阵的情况,他们需要提前知道怎么安排士 兵的行进路线可以使得整个部队的伤害值最小。

输入输出格式

输入格式:

第一行有两个整数 n,m,表示迷阵的大小。

接下来 n 行,每行 m 个数,第 i 行第 j 列的数表示 p[i][j]。

输出格式:

输出一个数,表示最小伤害代价。

输入输出样例

输入样例#1:

4 2

0 0

3 5

2 4

0 0

输出样例#1:

3

说明

50%的数据,n,m<=100;

100%的数据,n,m<=1000,p[i][j]<=1000。

思路:看到最大值最小很容易想到二分答案,然后n<=1000,可以用bfs来验证。但我一开始从(1,1)开始跑spfa,但不幸只有50,所以遇到二维地图还是乖乖bfs吧。

题解(二分):

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int map[1005][1005];
bool vis[1005][1005];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
struct edge{
int x,y;
};
queue<edge>q;
int n,m;
bool check(int mid)
{
memset(vis,0,sizeof(vis));
edge s;
s.x=1,s.y=1;
q.push(s);
vis[1][1]=1;
while(!q.empty())
{
edge u=q.front(); q.pop();
for(int i=0;i<4;i++)
{
int mx=u.x+dx[i],my=u.y+dy[i];
if(mx>=1&&mx<=n&&my>=1&&my<=m&&!vis[mx][my]&&map[mx][my]<=mid)
{
vis[mx][my]=1;
q.push((edge){mx,my});
}
}
}
bool flag=1;
for(int i=1;i<=m;i++)
{
if(!vis
[i])
{
flag=0;
}
}
if(!flag)
{
return 0;
}
else
{
return 1;
}
}
int main()
{
scanf("%d%d",&n,&m);
int l=0,r=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
r=max(r,map[i][j]);
}
}
int ans=21474836;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))
{
r=mid-1;
ans=min(ans,mid);
}
else
{
l=mid+1;
}
}
printf("%d",ans);
return 0;
}


50分spfa(雾):

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<queue>
using namespace std;
int map[1005][1005];
int dx[4]={1,0,0,-1};
int dy[4]={0,1,-1,0};
int n,m;
int dis[1005][1005];
bool vis[1005][1005];
struct cc{
int x,y;
};
queue<cc>q;
void spfa(int s1,int s2)
{
dis[s1][s2]=map[s1][s2];
vis[s1][s2]=1;
q.push((cc){s1,s2});
while(!q.empty())
{
cc u=q.front(); q.pop();
vis[u.x][u.y]=0;
for(int i=0;i<4;i++)
{
int mx=u.x+dx[i],my=u.y+dy[i];
if(mx>=1&&mx<=n&&my>=1&&my<=m)
{
if(dis[mx][my]>max(dis[u.x][u.y],map[mx][my]))
{
dis[mx][my]=max(dis[u.x][u.y],map[mx][my]);
if(!vis[mx][my])
{
vis[mx][my]=1;
q.push((cc){mx,my});
}
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
}
}
int ans=0;
memset(dis,63,sizeof(dis));
spfa(1,1);
for(int i=1;i<=m;i++)
{
ans=max(ans,dis
[i]);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: