搜索与图论

DFS

全排列的方法数

在这里插入图片描述

import java.util.*;
public class Main{
    static int n,N=10;     
    static int[]path=new int[N+1]; //路径结点
    static boolean[] st=new boolean[N]; //标记是否访问过
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        dfs(0); 
    }
    public static void dfs(int u){
        if(u==n){
            for(int i=0;i<n;i++)
            System.out.print(path[i]+" ");
            System.out.println();
            return; //回溯
        }
        for(int i=1;i<=n;i++){
            if(!st[i]){
                path[u]=i;
                st[i]=true;
                dfs(u+1);
                st[i]=false;
            }
        }
    }
}

n-皇后问题

在这里插入图片描述
遍历每一行,如果该点的所在列,主副对角线没有放置,则放置,递归遍历下一行,并回溯恢复,如果所有行遍历完则输出

import java.util.*;
class Main{
    static int N=20,n;
    static char[][]q=new char[N][N];
    static boolean []col=new boolean[N],dg=new boolean[N],udg=new boolean[N];
    static Scanner sc=new Scanner(System.in);
    public static void dfs(int r){
        if(r==n){
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    System.out.print(q[i][j]); 
                }
             System.out.println();
            }
            System.out.println();
            return;
        }
        for(int i=0;i<n;i++){
            if(!col[i]&&!dg[i+r]&&!udg[n-i+r]){
                q[r][i]='Q';
                col[i]=dg[i+r]=udg[n-i+r]=true;
                dfs(r+1);
                col[i]=dg[i+r]=udg[n-i+r]=false;
                q[r][i]='.';
            }
        }
    }
    public static void main(String[]args){
        n=sc.nextInt();
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                q[i][j]='.';
            }
        }
        dfs(0);
    }
}

BFS

走迷宫的最短路径

在这里插入图片描述

bfs保证每一次尽可能覆盖最大面积,走过则计算路径并标记,直到覆盖到终点就是最短路径

import java.util.*;
class Node{
	int x;
	int y;
	public Node(int x,int y){
		this.x=x;
		this.y=y;
	}
}
class Main{
	
	static int[][] matrix=null;
	static int row=0,col=0;
	static Scanner sc=new Scanner(System.in);
	
	public static void main(String[] args) {
		row=sc.nextInt();
		col=sc.nextInt();
		//matrix保存地图
		matrix=new int[row][col];
		//读取地图
		for(int i=0;i<row;i++){
			for(int j=0;j<col;j++){
				matrix[i][j]=sc.nextInt();
			}
		}
		System.out.println(bfs());
	}

	public static int bfs(){
		Queue<Node>q=new LinkedList();
		//保存该点到源点的距离
		int[][]dis=new int[row][col];
		//上下左右四个方向
		int[]r={-1,1,0,0};
		int[]c={0,0,-1,1};
		q.offer(new Node(0,0));

		while(!q.isEmpty()){
			Node cur=q.poll();
			if(cur.x==row-1&&cur.y==col-1){
				break;
			}
			for(int i=0;i<4;i++){
				int newx=cur.x+r[i];
				int newy=cur.y+c[i];
				if(newx>=0&&newx<row&&newy>=0&&newy<col&&dis[newx][newy]==0&&matrix[newx][newy]==0){
					dis[newx][newy]=dis[cur.x][cur.y]+1;
					q.offer(new Node(newx,newy));
				}
			}
		}
		return dis[row-1][col-1];
	}
}

权重为1的最短路径

邻接表保存有向图,初始化所有点到源点的距离为-1,邻接表的结点值也为-1,如果先将第一个点1入队,取出并遍历其所有关联的边(链表形式)的点,如果未确定距离,则计算距离+1,入队

import java.util.*;
class Main{
	static int idx,n,m;
	static int N=100010;
	static int[]dist=new int[N];
	static boolean []st=new boolean[N];
	static int[] h=new int[N];
	static int[] e=new int[N];
	static int[] ne=new int[N];
	static Queue<Integer>q=new LinkedList<>();
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();

		for(int i=0;i<N;i++){
			dist[i]=-1;
			h[i]=-1;
		}
		for(int i=0;i<m;i++){
			int a=sc.nextInt();
			int b=sc.nextInt();
			add(a,b);
	    }
		System.out.println(bfs(1));
	}
	public static void add(int a,int b){
		e[idx]=b;
		ne[idx]=h[a];
		h[a]=idx++;
	}
	public static int bfs(int u){
		dist[1]=0;
		q.offer(u);
		st[u]=true;
		while(!q.isEmpty()){
			int t=q.poll();
			for(int i=h[t];i!=-1;i=ne[i]){
				int j=e[i];
				if(!st[j]){
					dist[j]=dist[t]+1;
					q.offer(j);
					st[j]=true;
				}
			}
		}
		return dist[n];
	}
}

最短路径

Dijkstra算法

在这里插入图片描述

外层循环n-1次,每次找到距离源点最近的点赋值给t,通过1t,tj的距离更新1~j的距离

import java.util.*;
class Main{
	static int N=510,max=0x3f3f3f3f,n,m;
	static int [][]g=new int[N][N]; //g[a][b]表示a~b的距离
	static int []dist=new int[N];·//dist[i],i到源点的距离
	static boolean[]st=new boolean[N];
	public static int dijkstra(){
		Arrays.fill(dist,max);
		dist[1]=0;
		for(int i=0;i<n;i++){	
			int t=-1;
			for(int j=1;j<=n;j++){
				if(!st[j]&&(t==-1||dist[j]<dist[t])){
					t=j;
				}
			}
			st[t]=true;
			//用1~t+t~j的距离更新1~j的距离
			for(int j=1;j<=n;j++){
				dist[j]=Math.min(dist[j],dist[t]+g[t][j]);
			}
		}
		if(dist[n]==max)return -1;
		else return dist[n];

	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		for(int i=1;i<=n;i++){
			Arrays.fill(g[i],max);
		}
		while(m-->0){
			int a=sc.nextInt();
			int b=sc.nextInt();
			int c=sc.nextInt();
			g[a][b]=Math.min(g[a][b],c);
		}
		int res=dijkstra();
		System.out.println(res);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值