luogu P4011 孤岛营救问题 #10073. 「一本通 3.2 例 2」拯救大兵瑞恩

在这里插入图片描述

analysis

分层图最短路+01BFS
这里不需要建图,图在心中

code

#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
#define pos(x,y) (((x-1)*m+y))
template<typename T>void rd(T &x){
	x=0;char r=getchar();T neg=1;
	while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
	while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
	x*=neg;
}

const int maxn=10+10,maxm=10+10,maxp=10+10,maxk=200;
int n,m,p,k,s;
int a[maxn][maxn][maxn][maxn];//easier
int key[maxn][maxn][maxp];
int nfk[maxn][maxn];
struct node{
	int x;
	int y;
	int step;
	int state;
	node():x(0),y(0),step(0),state(0){}
	node(int x,int y,int step,int state):x(x),y(y),step(step),state(state){}
};
queue<node>q;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
bool vis[maxn][maxn][(1<<(maxp-10))+10];
void bfs(){
	q.push(node(1,1,0,0));
	while(q.empty()==false){
		node f=q.front();
		q.pop();
		if(f.x==n&&f.y==m){
			printf("%d\n",f.step);
			return;
		}
		loop(i,0,3){
			int nx=f.x+dx[i];
			int ny=f.y+dy[i];
			if(nx*ny==0||nx>n||ny>m)
				continue;
			int nstate=f.state;
			if(a[f.x][f.y][nx][ny]==-1||(a[f.x][f.y][nx][ny]>0&&(f.state&(1<<(a[f.x][f.y][nx][ny]-1))))){
				loop(i,1,nfk[nx][ny])
					nstate|=(1<<(key[nx][ny][i]-1));
				if(!vis[nx][ny][nstate]){
					q.push(node(nx,ny,f.step+1,nstate));
					vis[nx][ny][nstate]=true;
				}
			}
		}
	}
	printf("-1\n");
}
int main(){
	#ifndef ONLINE_JUDGE
	freopen("datain.txt","r",stdin);
	#endif
	clean(key,0);
	clean(a,-1);
	clean(nfk,0);
	clean(vis,false);
	
	rd(n);
	rd(m);
	rd(p);
	rd(k);
	loop(i,1,k){
		int xi,yi,xj,yj,gi;
		rd(xi);
		rd(yi);
		rd(xj);
		rd(yj);
		rd(gi);
		a[xi][yi][xj][yj]=gi;
		a[xj][yj][xi][yi]=gi;
	}
	
	rd(s);
	loop(i,1,s){
		int xi,yi,qi;
		rd(xi);
		rd(yi);
		rd(qi);
		key[xi][yi][++nfk[xi][yi]]=qi;
	}
	
	bfs();
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndrewMe8211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值