poj3271Lilypad Pondg

先預處理出每個點能到的需要建荷花的地方,把中間走的步數省略了,這樣再最短路到終點就是最少需要建的荷花數。

至於方案數,只要把上一個點的方案數加起來就好了。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
ll dir[8][2]={
	2,1,
	1,2,
	2,-1,
	-1,2,
	-2,1,
	1,-2,
	-1,-2,
	-2,-1
};
ll m,n;
ll map[50][50];
ll sx,sy,tx,ty;
int d[50][50][50][50];
bool inside(ll x,ll y)
{
	if(x>=1&&x<=m&&y>=1&&y<=n)return 1;
	return 0;
}
bool met[50][50];
void bfs1(ll x,ll y)
{
	memset(met,0,sizeof(met));
	queue<int>X;
	queue<int>Y;
	X.push(x);
	Y.push(y);
	met[x][y]=1;
	while(!X.empty())
	{
		ll ux=X.front();
		ll uy=Y.front();
		X.pop();
		Y.pop();
		for(ll i=0;i<8;i++)
		{
			ll xx=ux+dir[i][0];
			ll yy=uy+dir[i][1];
			if(inside(xx,yy))
			{
				if(met[xx][yy]==0)
				{
					met[xx][yy]=1;
					if(map[xx][yy]==1)
					{
						X.push(xx);
						Y.push(yy);
					}else
					{
						d[x][y][xx][yy]=1;
					}
				}
			}
		}
	}
}
ll ans[50][50];
ll dis[50][50];
ll len[50][50];
void bfs2()
{
	memset(ans,0,sizeof(ans));
	memset(dis,0x3f,sizeof(dis));
	queue<int>X;
	queue<int>Y;
	X.push(sx);
	Y.push(sy);
	ans[sx][sy]=1;
	dis[sx][sy]=0;
	len[sx][sy]=0;
	while(!X.empty())
	{
		ll ux=X.front();
		ll uy=Y.front();
		X.pop();
		Y.pop();
		if(map[ux][uy]==2)continue;
		for(ll i=1;i<=m;i++)
		{
			for(ll j=1;j<=n;j++)
			{
				if(d[ux][uy][i][j])
				{
					if(dis[i][j]==dis[ux][uy]+1)
					{
						ans[i][j]+=ans[ux][uy];
					}else if(dis[i][j]>dis[ux][uy]+1)
					{
						dis[i][j]=dis[ux][uy]+1;
						ans[i][j]=ans[ux][uy];
						X.push(i);
						Y.push(j);
					}
				}
			}
		}
	}
}
int main()
{
	while(scanf("%lld %lld",&m,&n)!=EOF)
	{
		for(ll i=1;i<=m;i++)
		{
			for(ll j=1;j<=n;j++)
			{
				scanf("%lld",&map[i][j]);
				if(map[i][j]==3)
				{
					sx=i;
					sy=j;
				}
				if(map[i][j]==4)
				{
					tx=i;
					ty=j;
				}
			}
		}
		memset(d,0,sizeof(d));
		for(ll i=1;i<=m;i++)
		{
			for(ll j=1;j<=n;j++)
			{
				bfs1(i,j);//預處理
			}
		}
		bfs2();
		if(dis[tx][ty]>25000)
		{
			printf("-1\n");
		}else
		{
			printf("%lld\n%lld\n",dis[tx][ty]-1,ans[tx][ty]);
		}
	}
	return 0;
}

usacoSilver Lilypad Pond, 2007 Feb

和這道題相似,但不能省略中間步數。https://www.byvoid.com/blog/usaco-feb07-silver-silver-lilypad-pond/說的很好。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章