请求开放题解通道
查看原帖
请求开放题解通道
577628
zgy_123楼主2023/10/7 13:25

如下,还有一种最短路解法,好理解,码量不多(比大部分题解都短),并且可过。https://www.luogu.com.cn/record/128105762

#include<bits/stdc++.h>
using namespace std;
int b[105][105],cnt,hd[2000005],d[2000005];
bool a[2000005];
struct node{
	int to,nxt;
}edge[2000005];
struct q{
	int dis,u;
	bool operator>(const q &a)const{return dis>a.dis;}
};
priority_queue<q,vector<q>,greater<q> > qu;
void add(int u,int v){
	edge[++cnt].to=v,edge[cnt].nxt=hd[u],hd[u]=cnt;
}
void dijkstra(int fr){
	memset(d,0x3f,sizeof(d));
	qu.push({0,fr});
	d[fr]=0;
	while(!qu.empty()){
		int x=qu.top().u;
		qu.pop();
		if(a[x]) continue;
		a[x]=1;
		for(int i=hd[x];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(d[v]>d[x]+1)
				d[v]=d[x]+1,qu.push({d[v],v});
		}
	}
}
#define chk(x,y) (x>0&&y>0&&x<=n&&y<=m&&b[x][y]==0)
int main(){
	int n,m,st=-1,ed;
	cin>>m>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			char ch;
			cin>>ch;
			if(ch=='*') b[i][j]=1;
			if(ch=='C'&&st==-1) st=(i-1)*m+j;
			else if(ch=='C'&&st!=-1) ed=(i-1)*m+j; 
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			if(b[i][j]) continue;
			int tot=(i-1)*m+j;
			for(int dis=1;;dis++)
				if(chk(i+dis,j)) add(tot,(i+dis-1)*m+j);
				else break;
			for(int dis=1;;dis++)
				if(chk(i,j+dis)) add(tot,(i-1)*m+j+dis);
				else break;
			for(int dis=1;;dis++)
				if(chk(i-dis,j)) add(tot,(i-dis-1)*m+j);
				else break;
			for(int dis=1;;dis++)
				if(chk(i,j-dis)) add(tot,(i-1)*m+j-dis);
				else break;
		}
	dijkstra(st);
	cout<<d[ed]-1;
	return 0;
}

2023/10/7 13:25
加载中...