比赛 4043级NOIP2022欢乐赛5th 评测结果 AAAAAAAAAAAAAAAAAA
题目名称 仓库管理员(Store-Keeper) 最终得分 100
用户昵称 op_组撒头屯 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2022-11-14 20:51:36
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N=100*100+5;
const int M=100*100*4+5;
const int inf=0x3f3f3f3f;
struct sdf{
	int to,next;
}eg[2*M];
int head[N],ne=0;
int n,m;
int sx,sy,tx,ty,px,py;
char mp[105][105];
inline int id(int x,int y){
	return (x-1)*m+y;
}
void add(int x,int y){
	eg[++ne]={y,head[x]};
	head[x]=ne;
	eg[++ne]={x,head[y]};
	head[y]=ne;
	return ;
}
int dfn[N]={0},low[N],tim=0;
bool isge[N]={0},no[N]={0};
int st[N],tp=0;
int cnt=0,did[N],geid[N];
void tarjan(int pt,int fa){
	dfn[pt]=low[pt]=++tim;
	st[++tp]=pt;
	if (fa==0&&head[pt]==0){
		did[pt]=++cnt;return ;
	}
	int num=0;
	for (int i=head[pt];i!=0;i=eg[i].next){
		int v=eg[i].to;
		if (v==fa)continue;
		if (!dfn[v]){
			tarjan(v,pt);
			low[pt]=min(low[pt],low[v]);
			if (low[v]>=dfn[pt]){
				num++;
				if (num>1||fa!=0)isge[pt]=1;
				int now;
				did[pt]=++cnt;
				geid[cnt]=pt;
				do{
					now=st[tp--];
					did[now]=cnt;
				}while(now!=v);
			}
		}
		else low[pt]=min(low[pt],dfn[v]);
	}
	return ;
}
struct wer{
	int xid,val,dir;
};
queue<wer>q;
bool vis[N]={0},yes[N],canget=0;
void bfs1(){
	q.push({id(px,py),0,0});
	vis[id(px,py)]=1;
	while(!q.empty()){
		wer t=q.front();q.pop();
		for (int i=head[t.xid];i!=0;i=eg[i].next){
			int v=eg[i].to;
			if (v==id(sx,sy)||vis[v])continue;
			vis[v]=1;q.push({v,0,0});
		}
	}
	return ;
}
int fx[]={1,-1,0,0},fy[]={0,0,1,-1};
int dis[N][5];
bool inmap(int x,int y){
	return (x>=1&&y>=1&&x<=n&&y<=m);
}
void bfs2(){
	while(!q.empty())q.pop();
	memset(dis,0x3f,sizeof(dis));
	for (int i=0;i<=3;i++){
		int nowx=sx+fx[i],nowy=sy+fy[i];
		if (inmap(nowx,nowy)&&!no[id(nowx,nowy)]&&vis[id(nowx,nowy)]){
			q.push({id(sx,sy),0,i^1});dis[id(sx,sy)][i^1]=0;
		}
	}
	while(!q.empty()){
		wer now=q.front();q.pop();
		int wx=(now.xid-1)/m+1,wy=now.xid%m;
		if (!wy)wy=m;
		int lstx=wx-fx[now.dir],lsty=wy-fy[now.dir];
		for (int i=0;i<=3;i++){
			int nowx=wx+fx[i],nowy=wy+fy[i],nid=id(nowx,nowy);
			int opsx=wx-fx[i],opsy=wy-fy[i];
			if (!inmap(nowx,nowy)||!inmap(opsx,opsy)||no[nid]||dis[nid][i]!=inf)continue;
			int lid=id(lstx,lsty),oid=id(opsx,opsy);
			if (did[lid]==did[oid]||geid[did[lid]]==oid||geid[did[oid]]==lid){
				q.push({nid,now.val+1,i});
				dis[nid][i]=now.val+1;
				if (nowx==tx&&nowy==ty){
					printf("%d\n",now.val+1);canget=1;
					return ;
				}
			}
		}
	}
}
int main(){
	freopen ("mag.in","r",stdin);
	freopen ("mag.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++){
		scanf("%s",mp[i]+1);
		for (int j=1;j<=m;j++){
			if (mp[i][j]=='M')px=i,py=j;
			if (mp[i][j]=='P')sx=i,sy=j;
			if (mp[i][j]=='K')tx=i,ty=j;
		}
	}
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			if (mp[i][j]=='S'){
				no[id(i,j)]=1;continue;
			}
			if (i!=1&&mp[i-1][j]!='S')add(id(i,j),id(i-1,j));
			if (j!=1&&mp[i][j-1]!='S')add(id(i,j),id(i,j-1));
			if (i!=n&&mp[i+1][j]!='S')add(id(i,j),id(i+1,j));
			if (j!=m&&mp[i][j+1]!='S')add(id(i,j),id(i,j+1));
		}
	}
	for (int i=1;i<=n*m;i++){
		if (!no[i]&&!dfn[i])tarjan(i,0);
	}
	bfs1();
	bfs2();
	if (!canget)printf("NIE\n");
	return 0;
}