【CCF 201604-4】游戏(BFS+优先队列)

版权声明: https://blog.csdn.net/leelitian3/article/details/82623689

写在前面

写博客之前搜索了一下网解,发现大家都是BFS+三维vis过的:CCF201604-4 游戏(100分)

这里分享一个BFS+优先队列的满分思路(如有错误请指正)

大致思路

每次从队列中找出d值最小的结点, 假设为u,由于使用的是优先队列,那么能够保证每次出队的u是最优的先驱。那么对于它的邻接结点v,有:

①若v在u.d+1的时间可达,那么v.d = u.d+1,且这是它的最短路径;

②若不可达(即v.begin ≤ u.d+1 ≤ v.end),那么就要等待一会让其过了危险时间v.end,等待期间需要来回踱步

        若等待时间为奇数,那么v.d = v.end+1

        若为偶数则为v.end+2

由于u.d是最先到达v附近的时间,所以此时v.d也是最短路径。

C++满分代码(带注释)

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

struct Node
{
	int x, y, d;
	Node(int a,int b,int c):x(a),y(b),d(c) {}
	bool friend operator < (const Node& a, const Node& b)
	{
		return a.d > b.d;
	}
};

int n,m,t,r,c,a,b;
int start[105][105];  //不能经过时间段的起始时间 
int stop[105][105];    //不能经过时间段的终止时间 
int d[105][105];        //每个点到源节点的最短路径 
bool vis[105][105];      //是否已经确定了最短路径 
priority_queue<Node> que; //优先队列 
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; //方向 

bool is_legal(int x, int y) //判断是否越界或者已经被找到最短路径 
{
	if(vis[x][y] == 1) return 0;
	if(x <= 0 || x > n || y <= 0 || y > m) return 0;
	return 1;
}

void bfs()
{
	int x, y, r, c, dis;
	que.push(Node(1,1,0));
	vis[1][1] = 1;
	while(!que.empty())
	{
		x = que.top().x; //每次找到d值最小的结点bfs 
		y = que.top().y;
		que.pop();
	//	cout<<"("<<x<<","<<y<<"): "<<d[x][y]<<"\n";
		for(int i=0; i<4; ++i)
		{
			r = x + dir[i][0];          //邻接的结点 
			c = y + dir[i][1];
			if(is_legal(r,c) == 0) continue;
			
			dis = d[x][y] + 1;
			if(start[r][c] !=0 && stop[r][c] != 0 && dis >= start[r][c] && dis <= stop[r][c]) //如果不能经过 
			{
				if((stop[r][c] - dis) & 1) dis = stop[r][c] + 1; //来回踱步,如果要踱步奇数次,那么时间为stop[r][c] + 1时就可以到达 
				else dis = stop[r][c] + 2; //偶数次,就要多走一步 
			}
			vis[r][c] = 1;
			d[r][c] = dis;
			que.push(Node(r,c,dis));  //加入队列 
		}
	}
}


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin>>n>>m>>t;
	while(t--)
	{
		cin>>r>>c>>a>>b;
		start[r][c] = a;
		stop[r][c] = b;
	}

	memset(d,0x3f3f3f3f,sizeof(d));  //设为无穷大 
	d[1][1] = 0;
	bfs();
	cout<<d[n][m];
	return 0;
}

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/82623689
今日推荐