2143: 飞飞侠

Dijkstra跑了25S差点以为要炸,回头看了一下发现时限是50S。。。。。。。。

难得在BZOJ上找到这么水的题。

NOIP水平不多说了。

#include
#include
#include
#include
using namespace std;
const int inf=1e9;
struct Heapnode{
	int x,y,d;
	bool operator<(const Heapnode &rhs)const{
		return d>rhs.d;
	}
};
int d[155][155],A[155][155],B[155][155],n,m;
bool done[155][155];
void dijkstra(int sx,int sy){
	priority_queueq;
	memset(d,0x3f,sizeof(d));d[sx][sy]=0;
	memset(done,false,sizeof(done));
	q.push((Heapnode){sx,sy,0});
	while(!q.empty()){
		Heapnode tmp=q.top();q.pop();
		int x=tmp.x,y=tmp.y;if(done[x][y])continue;
		done[x][y]=true;
		int l=x-B[x][y],r=x+B[x][y];
		for(int i=1;i<=B[x][y];i++){
			if(y-i<1)break;
			int tmpl=l+i,tmpr=r-i;
			tmpl=max(tmpl,1);tmpr=min(tmpr,m);
			for(int j=tmpl;j<=tmpr;j++)
			if(d[j][y-i]>d[x][y]+A[x][y]){
				d[j][y-i]=d[x][y]+A[x][y];
				q.push((Heapnode){j,y-i,d[j][y-i]});
			}
		}
		for(int i=1;i<=B[x][y];i++){
			if(y+i>m)break;
			int tmpl=l+i,tmpr=r-i;
			tmpl=max(tmpl,1);tmpr=min(tmpr,m);
			for(int j=tmpl;j<=tmpr;j++)
			if(d[j][y+i]>d[x][y]+A[x][y]){
				d[j][y+i]=d[x][y]+A[x][y];
				q.push((Heapnode){j,y+i,d[j][y+i]});
			}
		}
		l=max(l,1);r=min(r,n);
		for(int i=l;i<=r;i++)
		if(d[i][y]>d[x][y]+A[x][y]){
			d[i][y]=d[x][y]+A[x][y];
			q.push((Heapnode){i,y,d[i][y]});
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)scanf("%d",&B[i][j]);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)scanf("%d",&A[i][j]);
	int x[3],y[3],ans[3];
	for(int i=0;i<3;i++)scanf("%d%d",&x[i],&y[i]);
	memset(ans,0,sizeof(ans));
	for(int i=0;i<3;i++){
		dijkstra(x[i],y[i]);
		for(int j=0;j<3;j++)
		ans[j]+=d[x[j]][y[j]];
	}
	int res=1e9,p;
	for(int i=0;i<3;i++)
	if(ans[i]=inf){printf("NO");return 0;}
	switch(p){
		case 0:printf("X");break;
		case 1:printf("Y");break;
		case 2:printf("Z");break;
	}
	printf("\n%d",res);
	return 0;
}
		


你可能感兴趣的:(最短路)