万能的搜索之深度优先搜索算法
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 ;
}
}
浙公网安备 33010602011771号