POJ3278 -- BFS

这是一道非常简单的BFS。在这里需要注意的是,要对数据进行剪枝,否则会浪费时间。

在这里,我们用了俩种数据结构,分别是队列和数组的方式,来实现BFS。

一。首先我们来看一下通过自定义循环队列的BFS具体实现:

int BFS(int Person, int cow){
    que* q = (que*)malloc(sizeof(que));
    initQue(q);
    enQ(q,Person);
    count[Person]=0;
    while(q->front!=q->rear){
        int data = deQ(q);
        if(data == cow){
            return count[data];
        }
        if(data>0 && count[data-1] == -1){  //X-1
           enQ(q,data-1);
           count[data-1] = count[data]+1;
        }
        if(data<=cow && count[data+1] == -1){  //X+1
            enQ(q,data+1);
            count[data+1] = count[data]+1;
        }
        if(data<=cow && count[2*data] == -1 ){
            enQ(q,2*data);
            count[2*data] = count[data]+1;
        }
    }
}

1.首先将第一个数据5,进队列。此时队列为: 5

2.然后进入while循环,当队列不为空时,将第一个数据5出队, 并将4/7/10入队。 此时队列为:4 7 10

3.此时,在入队之前,进行判断,该数值是否被访问过(通过count[]数组),以及是否满足入队的条件(大于0且小于牛的距离17)。

 

二。通过数组进行模拟队列的BFS实现。

1。首先定义一个数据结构data,存放当前的坐标值x和走的步数step。

2。通过数组queue[MAX] 来存放这个自定义的数据结构data

 

#include <stdio.h>
#include <stdlib.h>


#define MAX 1<<20

int start ,end;

typedef struct data{
	int x;
	int step;
}data;
data queue[MAX];
int flag[MAX];

int BFS(){
	int rear=0;
	int front =0 ;
	int i=0;
	int temp_end=0;
	queue[rear].x =start;
	queue[rear].step =0;
	flag[start]=1;
	rear++; 

	while(front!=rear){  
	
	int temp_x =queue[front].x;
	int temp_step = queue[front].step;
	front++;  

	if(temp_x == end){
		printf("%d\n",temp_step);
		break;
	}

	for(i=0;i<3;i++){
		if(i==0 && temp_x>0) temp_end = temp_x-1;
		if(i==1 && temp_x<=end) temp_end = temp_x+1;
		if(i==2 && temp_x<=end) temp_end = 2*temp_x;

		if(flag[temp_end]==0){  
		queue[rear].x = temp_end;
		queue[rear].step = temp_step+1;
		flag[temp_end]=1;
		rear=(rear+1);
		}
	}
	}
	return 1;
}

int main(){

	memset(queue,0,sizeof(queue));
	memset(flag,0,sizeof(flag));
	freopen("input.txt","r",stdin);
	scanf("%d%d",&start,&end);
	BFS();


	return 0;
}


需要注意的一点是,在进行-1操作时,判断条件是temp_x>0 ,而不是temp_x>=0,否则会数组越界,flag[-1], POJ提交时,一直报Runtime error


.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值