万能的搜索之深度优先搜索算法

package Graph;

import java.util.Scanner;


/**
 * 首先访问一个未被访问的顶点作为起始点,访问其所有的
 * 相邻的顶点,然后对每个相邻的顶点,再访问他们相邻的
 * 未被访问的顶点,一直到所有的顶点都被访问过一遍。
 * 
 * @author Administrator
 *
 */

public class Main5 {

	private static int i,j,n,m,a,b,cur;
	private static int [] book;
	private static int [][]e;
	private static int [] que;
	private static int head;
	private static int tail;
	
	
	
	
	public static void main(String[] args) {
		book = new int[101];
		e = new int[101][101];
		for(int i=0;i<book.length;i++){
			book[i] = 0;
			for(int j = 0;j<e[i].length;j++){
				e[i][j] = 0;
			}
		}
		que = new int [10001];
		
		Scanner input = new Scanner(System.in);
		n = input.nextInt();
		m = input.nextInt();
		//初始化二维矩阵
		for(i = 1;i<=n;i++)
		{
			for(j = 1;j<=n;j++)
			{
				if(i == j)
				{
					e[i][j] = 0;
				}else{
					e[i][j] = 9999999;
				}
			}
		}
		
		//读入顶点之间的边
		for(i = 1;i<=m;i++)
		{
			a = input.nextInt();
			b = input.nextInt();
			e[a][b] = 1;
			e[b][a] = 1;
		}
		//队列初始化
		head = 1;
		tail = 1;
		//从1号城市出发,将1号顶点已经访问
		que[tail] = 1;
		tail++;
		book[1] = 1;//标记1号顶点已经访问
		//当队列不为空的时候循环
		while(head < tail)
		{
			cur = que[head];//当前正在访问的顶点的编号
			for(i = 1;i<=n;i++)//从1-n依次尝试
			{
				//判断从顶点cur到顶点i是否有边,并且判断顶点i是不是被访问过
				if(e[cur][i] == 1 && book[i] == 0)
				{
					//如果从顶点cur到顶点i有边,并且顶点i没有被访问过,就将顶点i入队
					que[tail] = i;
					tail++;
					book[i] = 1;//标记顶点i已经被访问过
				}
				//如果tail大于n,就表明所有的顶点都已经被访问过
				if(tail >n){
					break;
				}
				
				
				
				
				
			}
			head++;//不要忘记当一个顶点扩展结束后,head++,然后才能继续往下扩展
			
			
		}
		for(i = 1;i<tail;i++)
		{
			System.out.printf("%d",que[i]);
		}
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	}
	
}

  

package Graph; import java.util.Scanner; /** * * @author Administrator * */ public class Main4 { private static int [] book; private static int sum; private static int n; private static int [][] e; public static void main(String[] args) { book = new int[101]; e = new int [101][101]; for(int i = 0;i<book.length;i++){ book[i] = 0; for(int j = 0;j<e[i].length;j++){ e[i][j] = 0; } } int i,j,m = 0,a,b; Scanner input = new Scanner(System.in); n = input.nextInt(); m = input.nextInt(); //初始化二维矩阵 for(i = 1;i<=n;i++) { for(j = 1;j<=n ;j++) { if(i == j) { e[i][j] = 0; }else{ e[i][j] = 999999999; } } } //读入顶点之间的边 for(i=1;i<=m;i++) { a = input.nextInt(); b = input.nextInt(); e[a][b] = 1; e[b][a] = 1;//这里是无向图,所以需要将e[b][a]也赋值为1 } //从1号城市出发 book[1] = 1;//标记1号顶点已经访问过 dfs(1);//从1号顶点开始遍历 } private static void dfs(int step) {//当前所在的顶点的编号 System.out.printf("%d",step); sum++;//每访问一个顶点sum就加1 if(sum == n)//所有的顶点都已经访问过了,就直接退出 { return; } for(int i = 1;i<=n;i++)//从1号城市到n号顶点依次尝试,看那些顶点与当前顶点cur有边相连接 { //判断当前顶点cur到顶点i是否有边,并且判断顶点i是否已经访问过 if(e[step][i] == 1 && book[i] == 0) { book[i] = 1;//标记顶点i已经访问过 dfs(i);//从顶点i再出发继续遍历 } } return ; } }

  

全排列

package Graph;

import java.util.Scanner;


/**
 * 万能的搜索:输入一个数字,输出1-n的全排列,
 * @author Administrator
 *
 */

public class Main {

	private static int n;
	private static int a[];
	private static int [] book;
	public static void main(String[] args) {
		a = new int [10] ;//表示盒子
		for(int i=0;i<n;i++){
			a[i] = 0;
		}
		book = new int[10];//标记
		for(int i=0;i<n;i++)
		{
			book[i] = 0;
		}
		Scanner input = new Scanner(System.in);
		 n = input.nextInt();//首先输入一个n
		dfs(1);
		
		

	}

	private static void dfs(int step) {//现在站在第几个盒子面前
		int i;
		if(step == n+1)//如果站在第n+1个盒子面前,则表示前n个盒子已经排好了顺序
		{
			//输出一种排列(1-n号盒子中的扑克牌编号)
			for(i = 1;i<=n;i++)
			{
				System.out.print(a[i]+"  ");
			}
			System.out.println();
			return ;//返回之前的一步(最近一次调用dfs的地方)
		}
		
		//此时站在第step个盒子面前,应该放那张牌?
		//按照1,2,3,。。。的顺序一一尝试
		for(i=1;i<=n;i++)
		{
			//判断扑克牌是不是在手中
			if(book[i] == 0)//book[i]等于0表示i号扑克在手中
			{
				//开始尝试使用扑克牌i
				a[step] = i;
				book[i] = 1;//将book[i] = 1表示i号扑克牌已经不在手中
				//第step个盒子已经放好扑克牌,接下来走到下一个盒子面前
				dfs(step+1);
				book[i]=0;//将刚才尝试的扑克牌收回
				
				
			}
		}
		
		
		
		
		
		
		
		
	}

}

  

package Graph;

import java.util.Scanner;

public class Main2 {

	private static int n;
	private static int[]a;
	private static int[]book;
	private static int total = 0;
	public static void main(String[] args) {
		a = new int[10];
		book = new int[10];
		for(int i = 0;i<n;i++){
			a[i] = 0;
			book[i] = 0;
		}
		Scanner input = new Scanner(System.in);
		n = input.nextInt();//输入自己想要的数字
		dfs(1);
		System.out.println(total/2);
		
		
		
		

	}

	private static void dfs(int step) {//step表示现在站在第几个盒子面前
		int i;
		if(step == n+1)//如果站在第n+1盒子面前,表示前n个盒子已经按照需求拍好了顺序
		{
			//判断是不是满足不等式XXX+YYY=ZZZ
			if(a[1] *100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6] == a[7]*100+a[8]*10+a[9])
			{
				//满足需求,可行解+1,并且打印结果
				total++;
				System.out.printf("%d%d%d+%d%d%d=%d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
				
			}
			
			return ;//返回之前调用的地方
			
		}
		//此时站在第step个盒子的面前,应该放那张牌呢
		//按照1,2,3,。。。。的顺序一一尝试
		for(i=1;i<=n;i++)
		{
			//判断扑克牌是不是还在手上
			if(book[i] == 0)//book[i]=0表示扑克牌还在手上
			{
				//开始尝试使用扑克i
				a[step] = i;//将扑克牌i 放入到第step盒子中
				book[i] = 1;//将book[i]设置为1表示不在手上,已经在盒子中
				//第step个盒子已经放置好扑克牌,走到下一个盒子面前
				dfs(step+1);
				book[i] = 0;//一定要将刚才尝试的牌收回,才能进行下一次的尝试
				
				
				
				
				
				
				
				
				
				
			}
		}
		
		
		return ;
		
	}

}

  

package Graph;

import java.util.Scanner;

public class Main3 {

	private static int i,j,startx,starty;
	private static int m,n,p,q,min = 999999;
	private static int [][]a;
	private static int [][]book;
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		a = new int[51][51];
		book = new int[51][51];
		n = input.nextInt();
		m = input.nextInt();
		//读入迷宫
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				a[i][j] = input.nextInt();
			}
		}
		//读入起点和终点坐标
		startx = input.nextInt();
		starty = input.nextInt();
		p = input.nextInt();
		q = input.nextInt();
		//从起点开始搜索
		book[startx][starty] = 1;//标记起点已经在路径中了,防止后面重复走
		//第一个参数是起点的x的坐标,第二个参数是起点的y坐标,第三个参数初始化步数为0
		dfs(startx,starty,0);
		
		System.out.println(min);

	}
	private static void dfs(int x, int y, int step) {
	//定义一个方向的二维数组
		int next[][] = {{0,1},{1,0},{0,-1},{-1,0}};
		int tx,ty,k;
		//判断是否到达小哈的位置
		if(x==p && y == q)
		{
			//更新最小值
	        if(step < min)
	        {
	        	min = step;
	        }
	        return ;//返回很重要
		}
		//枚举4种的走法
		for(k = 0;k<=3;k++)
		{
			//计算下一个点的坐标
			tx = x+next[k][0];
			ty = y+next[k][1];
			//判断是不是越界
			if(tx < 1 || tx >n||ty<1|| ty>m)
			{
				continue;
			}
			//判断该点是不是障碍物或者已经在路径中
			if(a[tx][ty] == 0 && book[tx][ty] == 0)
			{
				book[tx][ty] = 1;//标记这个点已经走过
				dfs(tx,ty,step+1);//开始尝试下一个点
				book[tx][ty] = 0;//尝试结束这个点
			}
			
			
			
			
			
			
			
			
			
			
		}
		return ;
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	}

}

  

posted on 2015-04-02 15:00  aicpcode  阅读(173)  评论(0编辑  收藏  举报

导航