扩散(多源广搜)

小蓝在一张无限大的特殊画布上作画。

这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。

小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)

只有这几个格子上有黑色,其它位置都是白色的。

每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。

请问,经过 2020分钟后,画布上有多少个格子是黑色的。
分析:四个点同时扩散,要考虑到重叠的问题,而且越是后面一秒扩散的点越多,开始写的是每个点分别广搜一遍,如果第一个点扩散到了第二个点且已经标记了,到第二个点的时候就不会搜索了,结果也就错了;
所以多源头同时搜索,当有点重叠的时候,先来的源头点说明剩余的时间更多,后续扩散的范围也最大,后来的源头点时间少,扩散范围肯定没有先来的大;

再说一下为什么不用广搜,2020个节点复杂度高,时间长,广搜可以通过空间来节省时间

#include
using namespace std;
int ans=4;
int book[9999][9999];
int nex[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
	int x,y,z;
}l,head;
queue <node> q;
void  bfs()
{
	while( !q.empty() )
	{
		head=q.front();
		q.pop();
		if(head.z>=2020)
		continue;
		for(int i=0;i<4;i++)
		{
			int tx=head.x+nex[i][0];
			int ty=head.y+nex[i][1];
			if(book[tx][ty]==0)
			{
				book[tx][ty]=1;
				ans++;
				l.x=tx;
				l.y=ty;
				l.z=head.z+1;
				q.push(l);
			}
		}
	}
}
int main()
{	
	book[3000][3000]=1;
	book[5020][3011]=1;
	book[3011][3014]=1;
	book[5000][5000]=1;
	l.x=3000;
	l.y=3000;
	l.z=0;
//	q.push(l);	
 q.push({3000,3000,0});
 //这样写也可以,前边已经规定队列为结构体类型
//	bfs();
	
	l.x=5020;
	l.y=3011;
	l.z=0;
	q.push(l);	
//	bfs();
	
	l.x=3011;
	l.y=3014;
	l.z=0;
	q.push(l);	
//	bfs();

	l.x=5000;
	l.y=5000;
	l.z=0;
	q.push(l);	
	bfs();
	printf("%d\n",ans);
}

你可能感兴趣的:(深搜广搜,c++,图论,链表)