万能的搜索之深度优先搜索算法
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 ; } }