Java算法学习12——经典问题的DFS和BFS


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Vector;

/*
 * 本节主要描述的dfs和bfs的方法。
 * 1.DFS
 * dfs其实就是在一种情况下一直搜寻直到碰壁,用递归实现dfs可以从递归边界
 * 和递归体进行考虑,递归边界即碰壁情况,递归体则是选或者不选,注意可以在递归体中进行剪枝
 * 即设置一下条件提前筛走
 * 2.BFS
 * bfs就是一层一层去搜索,利用队列来实现,当这一层的所有的选择都访问完了之后才进行下一层的选择
 * 常常和最短步数相联系
 * 
 * 易错点:
 * 注意Queue是一个接口,可以通过实例LinkedList和PriorityQueue来实现
 * 如Queue<Integer> q=new LinkedList<>();
 * Queue<Integer> q=new PriorityQueue<>();
 * 此外,当需要读入字符时,可以通过cin.next.charAt(0)消去换行符,cin.next()是读入下一个字符串的
 */
public class _dfsNbfs {

//DFS1:从n个物品中选择在给定重量中价值最高的
	static int n;//物品总数
	static int maxn=30;//最大物品数
	static int []w=new int [maxn];static int []v=new int [maxn];//物品所对应的重量和价值
	static int sumw,sumv,finalsumv,maxw;
	static void DFS(int index,int sumw,int sumv) {
		if(index==n) {
			if(sumv>finalsumv) {
				finalsumv=sumv;
			}
			return;//已经完成对n个物品的选择
		}else {
			DFS(index+1,sumw,sumv);//不选择这个
			if(sumw+w[index]<=maxw) {
				DFS(index+1,sumw+w[index],sumv+v[index]);
			}
		}
	}
//DFS2:从N个整数中选择K个数的所有方案,这个K个数的和为X
	static int []A=new int [maxn];//存储原始的无序数组
	static Vector<Integer>temp;//存储最佳方案
	static Vector<Integer> ans;
	static int x=0,k=0;//需要满足的和值
	static int sumSqumax=0;//时刻要更新的最大和值
	static void DFS2(int index,int nowk,int sumn,int sumSqu) {
		if(nowk==n&&sumn==x)//个数为k且总数为x 
		{
			if(sumSqu>sumSqumax) {
				sumSqumax=sumSqu;
				ans=temp;
			}
		}
		if(n==index||nowk>k||sumn>x) {
			return;
		}
		temp.add(A[index]);//选了
		DFS2(index+1,nowk+1,sumn+A[index],sumSqu+A[index]*A[index]);
		//如果是可以重复选,则上一步就要改成:
		//DFS2(index,nowk+1,sumn+A[index],sumSqu+A[index]*A[index])
		temp.removeElement(A[index]);
		//不选
		DFS2(index+1,nowk+1,sumn,sumSqu);
	}	
	
//BFS1:选取“1”的块数
/*
 * 广搜的基本操作:
 * (1)写BFS主体
 * (2)定义x,y的四个方向
 * (3)定义点的判断函数
 */
	static class node{
		int x;
		int y;
		int step;
		node(){}
	}
	static int xz[]= {0,0,1,-1};
	static int yz[]= {-1,1,0,0};
	static boolean inq[][];
	static boolean judge(int x,int y) {
		if(x<0||x>=n||y<0||y>=n) return false;
		else if(inq[x][y]=true) return false;
		else return true;
	}
	static void BFS(int x,int y) {
		Arrays.fill(inq, false);
		Scanner cin=new Scanner(System.in);
		Queue<node>q=new LinkedList<>();
		node k=new node();
		k.x=cin.nextInt();k.y=cin.nextInt();
		cin.nextInt();
		q.add(k);
		inq[x][y]=true;
		while(!q.isEmpty()){
			node newnode=q.poll();
			int newx,newy;
			for(int i=0;i<4;i++) {
				newx=newnode.x+xz[i];
				newy=newnode.y+yz[i];
				if(judge(newx,newy)) {
					k.x=newx;k.y=newy;
					q.add(k);
					inq[newx][newy]=true;
				}//PS:如果需要判断块数多少的话,可以在main函数里面判断,即遍历所有的点,然后如果发现inq[i]=false的话就
				//块数+1,然后再进行BFS把这一个点联通块都访问了
			}
		}
	}
	
//BFS2:
	static int BFS2(int x,int y) {
		node T=new node();//终点
		node S=new node();
		S.x=x;S.y=y;
		Queue<node> q=new LinkedList<>();
		q.add(S);
		inq[x][y]=true;
		while(!q.isEmpty()) {
			node newnode=q.poll();
			if(newnode.x==T.x&&newnode.y==T.y) {
				return newnode.step;//达到终点的最佳步数
			}
			for(int i=0;i<4;i++) {
				int newx=newnode.x+xz[i];
				int newy=newnode.y+yz[i];
				if(judge(newx,newy)) {
					newnode.x=newx;newnode.y=newy;
					q.add(newnode);
					inq[newx][newy]=true;
				}
				
			}
			
			
		}
		return -1;
	}
	
	public static void main(String []args) {
		Scanner cin=new Scanner(System.in);
		n=cin.nextInt();maxw=cin.nextInt();
		for(int i=0;i<n;i++) {
			w[i]=cin.nextInt();
		}
		for(int i=0;i<n;i++) {
			v[i]=cin.nextInt();
		}
		DFS(0,0,0);
		System.out.println(finalsumv);
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值