https://ac.nowcoder.com/acm/contest/878/A
很好的bfs模拟题,记录一下
要对于每个人找到离它最近的出口,而且优先上边再优先左边的出口,那么就是从上到下,从左到右得把出口放进队列,然后进行bfs,一个位置只能进队列一次,这样就能知道每个位置要去哪个出口排队。
再把每个人到对应出口的时间记录下来,放到那个出口上。
再对每一个出口,先按时间把要出去的人进行排序,使用一个优先队列,来判断每一时刻力量最大的人出去,时间++
如果当前时间等于还没进来的最早的人(队首)的时间,那么就while进优先队列。
如果当前队首时间大于当前时间,且优先队列中没人了(这里一开始没加这个判断),那么就跳转时间
当时还有输出错了,我以为是有人没出去直接输出-1,而实际是对于不能出去的人输出-1,其他人还是输出逃出时间
#include<bits/stdc++.h>
#define maxl 1010
using namespace std;
int n,m,p;
int tx[5]={0,1,0,-1,0};
int ty[5]={0,0,1,0,-1};
int ans[maxl*maxl];
int dis[maxl][maxl];
struct peo
{
int x,y,w;
}a[maxl*maxl];
struct que
{
int id,tm;
};
vector <que> ext[maxl][maxl];
struct pr
{
int x,y;
bool operator < (const pr &b)const
{
if(x==b.x)
return y<b.y;
return x<b.x;
}
}outto[maxl][maxl];
char ch[maxl][maxl];
queue <pr> q;
priority_queue <pr> priq;
inline void prework()
{
for(int i=1;i<=n;i++)
scanf("%s",ch[i]+1);
for(int i=1;i<=p;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
ans[i]=-1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ext[i][j].clear();
}
inline bool cmp(const que &x,const que &y)
{
if(x.tm==y.tm)
{
return a[x.id].w>a[y.id].w;
}
return x.tm<y.tm;
}
inline void mainwork()
{
while(!q.empty()) q.pop();
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(ch[i][j]=='2')
{
q.push(pr{i,j});
outto[i][j]=pr{i,j};
dis[i][j]=0;
}
pr u;int xx,yy;
while(!q.empty())
{
u=q.front();q.pop();
for(int i=1;i<=4;i++)
{
xx=u.x+tx[i];yy=u.y+ty[i];
if(xx>=1 && xx<=n && yy>=1 && yy<=m && ch[xx][yy]!='1')
{
if(dis[xx][yy]>dis[u.x][u.y]+1)
{
dis[xx][yy]=dis[u.x][u.y]+1;
outto[xx][yy]=outto[u.x][u.y];
q.push(pr{xx,yy});
}
}
}
}
int tm;
for(int i=1;i<=p;i++)
if(dis[a[i].x][a[i].y]<dis[0][0])
{
u=outto[a[i].x][a[i].y];
tm=dis[a[i].x][a[i].y];
ext[u.x][u.y].push_back(que{i,tm});
}
int l,k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
l=ext[i][j].size();
if(l==0) continue;
sort(ext[i][j].begin(),ext[i][j].end(),cmp);
k=0;
tm=0;
while(!priq.empty()) priq.pop();
do
{
if(k<l && ext[i][j][k].tm>tm && priq.empty())
tm=ext[i][j][k].tm;
while(k<l && ext[i][j][k].tm==tm)
{
priq.push(pr{a[ext[i][j][k].id].w,ext[i][j][k].id});
k++;
}
u=priq.top();priq.pop();
ans[u.y]=tm;
tm++;
}while(k<l || !priq.empty());
}
}
inline void print()
{
for(int i=1;i<=p;i++)
printf("%d%c",ans[i],(i==p)?'\n':' ');
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&p))
{
prework();
mainwork();
print();
}
return 0;
}