B. Chamber of Secrets (BFS || 0/1BFS) Croc Champ 2012 - Round 1

B. Chamber of Secrets (BFS || 0/1BFS) Croc Champ 2012 - Round 1_第1张图片

链接https://codeforces.com/contest/173/problem/B

题意:给定一个n\times m 的矩阵,然后有些单元格上有柱子。灯光穿过柱子的时候,可以直接穿过,也可以花费 1 ,向四个方向折射。现有一束光从第一行右边射出,然后要求从最后一行右边射出,求最少的花费。

思路

  1. 可以是普通的BFS,把每一行上所有柱子看成一个点,把每一列上的柱子看成一个点。然后BFS即可
  2. 分成需要花费和不需要花费,不需要花费放在队首,需要花费放在队尾。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+5,mod=1e9+7;
const int inf=0x3f3f3f3f;

int n,m;
int cost[maxn][maxn][4];
char grid[maxn][maxn];
int Move[][2]={{-1,0},{0,1},{1,0},{0,-1}};

struct node
{
	int x,y,dir;
};

void bfs()
{
	queue<node> q;
	q.push({n,m,3});
	cost[n][m][3]=0;
	
	while(!q.empty())
	{
		node t=q.front();
		q.pop();

		int nx=t.x+Move[t.dir][0];
		int ny=t.y+Move[t.dir][1];
		int c=cost[t.x][t.y][t.dir];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m)
		{
			if(cost[nx][ny][t.dir]>c)
			{
				cost[nx][ny][t.dir]=c;
				q.push({nx,ny,t.dir});	
			}
		}	
		if(grid[t.x][t.y]=='#')
		{
			for(int i=0;i<4;++i)
			{			
				if(i!=t.dir&&cost[t.x][t.y][i]>c+1)
				{
					cost[t.x][t.y][i]=c+1;
					q.push({t.x,t.y,i});							
				}			
			}				
		}
	}	
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%s",grid[i]+1);
	
	memset(cost,inf,sizeof(cost));
	bfs();
	if(cost[1][1][3]!=inf)
		printf("%d\n",cost[1][1][3]);
	else
		puts("-1");
	return 0;
}

0/1 BFS

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+5,mod=1e9+7;
const int inf=0x3f3f3f3f;

int n,m;
int cost[maxn][maxn][4];
char grid[maxn][maxn];
int Move[][2]={{-1,0},{0,1},{1,0},{0,-1}};

struct node
{
	int x,y,dir;
};

void bfs()
{
	deque<node> q;
	q.push_back({n,m,3});
	cost[n][m][3]=0;
	
	while(!q.empty())
	{
		node t=q.front();
		q.pop_front();
		if(cost[1][1][3]!=inf)
			break;
		

		int nx=t.x+Move[t.dir][0];
		int ny=t.y+Move[t.dir][1];
		int c=cost[t.x][t.y][t.dir];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m)
		{
			if(cost[nx][ny][t.dir]>c)
			{
				cost[nx][ny][t.dir]=c;
				q.push_front({nx,ny,t.dir});	
			}
		}	
		if(grid[t.x][t.y]=='#')
		{
			for(int i=0;i<4;++i)
			{			
				if(i!=t.dir&&cost[t.x][t.y][i]>c+1)
				{
					cost[t.x][t.y][i]=c+1;
					q.push_back({t.x,t.y,i});							
				}			
			}				
		}
	}	
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%s",grid[i]+1);
	
	memset(cost,inf,sizeof(cost));
	bfs();
	if(cost[1][1][3]!=inf)
		printf("%d\n",cost[1][1][3]);
	else
		puts("-1");
	return 0;
}

BFS

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+5,mod=1e9+7;
const int inf=0x3f3f3f3f;

int n,m;
char s[maxn];
vector<int> G[maxn<<1];
bool visit[maxn<<1];
int depth[maxn<<1];

void bfs()
{
	queue<int> q;
	visit[n]=true;
	q.push(n);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(auto v: G[u])
		{
			if(!visit[v])
			{
				visit[v]=true;
				depth[v]=depth[u]+1;
				q.push(v);
				if(v==1)
					return;
			}			
		}		
	} 	
} 

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%s",s+1);
		for(int j=1;j<=m;++j)
		{
			if(s[j]=='#')
			{
				G[i].push_back(j+n);
				G[j+n].push_back(i);
			} 
		}
	}
	bfs();
	if(depth[1]||1==n)
		printf("%d\n",depth[1]);
	else
		puts("-1");
	return 0;
}

你可能感兴趣的:(CF,图论,-,BFS)