算法题——图论

98.可达路径

使用深度优先遍历进行递归

邻接矩阵存储,进行深度优先遍历

java 复制代码
import java.util.*;
 
public class Main{
    static List<List<Integer>> res = new ArrayList<>();
 
    static List<Integer> path = new ArrayList<>(); 
 
    public static void dfs(int[][] graph, int cur, int target){
        if(cur==target){  //如果当前遍历的就是目标节点,则说明找到了一条路径
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i=1;i<=target;i++){ //遍历当前节点对应的邻接矩阵的一行,与当前节点相连的节点可以加入路径
            if(graph[cur][i]==1){
                path.add(i);
                dfs(graph, i, target);
                path.remove(path.size()-1);
            }
        }
    }
 
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
 
        int[][] graph = new int[n+1][n+1]; //定义邻接矩阵
        while(m--!=0){
            int s = sc.nextInt();
            int t = sc.nextInt();
            graph[s][t] = 1;  //对应边的位置
        }
        path.add(1);  ////题目要求从1开始,所以path第一个元素必须是
        dfs(graph, 1, n);
 
        if(res.isEmpty()) System.out.println(-1); //处理输出
        for(List<Integer> list : res){
            for(int i=0;i<list.size()-1;i++){
                System.out.print(list.get(i) + " ");
            }
            System.out.println(list.get(list.size()-1));
        }
    }
}

邻接表存储,进行深度优先遍历

java 复制代码
import java.util.*;

public class Main {
    static List<List<Integer>> res = new ArrayList<>();
    static List<Integer> path = new ArrayList<>();

    static void dfs(List<LinkedList<Integer>> graph, int cur, int target) {
        if (cur == target) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i : graph.get(cur)) { //遍历当前节点对应的链表,链表上的节点可以加入路径
            path.add(i);
            dfs(graph, i, target);
            path.remove(path.size() - 1);
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        List<LinkedList<Integer>> graph = new ArrayList<>(n + 1);//定义邻接表
        for(int i=0;i<=n;i++){  //初始化邻接表的边表(链表)
            graph.add(new LinkedList<Integer>());
        }
        while (m-- > 0) {
            int s = sc.nextInt();
            int t = sc.nextInt();
            graph.get(s).add(t); //将边的信息加入邻接表
        }
        path.add(1); //题目要求从1开始,所以path第一个元素必须是1
        dfs(graph, 1, n);
        if (res.isEmpty()) System.out.println(-1); //处理输出
        for (List<Integer> list : res) {
            for (int i = 0; i < list.size() - 1; i++) {
                System.out.print(list.get(i) + " ");
            }
            System.out.println(list.get(list.size() - 1));
        }
    }
}

要熟悉邻接矩阵和邻接表存储图的过程,熟悉dfs遍历的写法

99.计数孤岛

本题思路是用遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。

在遇到标记过的陆地节点 和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量

深度优先遍历的写法:

java 复制代码
import java.util.*;

public class Main{
    public static int[][] dir = {{0,-1}, {0,1}, {-1,0}, {1,0}}; //四个方向
    public static void dfs(boolean[][] visited, int[][] graph, int x, int y){
        //获取四个方向的坐标
        for(int i=0;i<4;i++){
            int nextX = x+dir[i][0];
            int nextY = y+dir[i][1];
            if(nextX<0 || nextY<0 || nextX>=graph.length || nextY>=graph[0].length) continue;
            if(!visited[nextX][nextY] && graph[nextX][nextY]==1){
                //该位置未被访问过,且为陆地
                visited[nextX][nextY] = true;
                dfs(visited, graph, nextX, nextY);
            }
        }
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[][] graph = new int[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                graph[i][j] = sc.nextInt();
            }
        }
        boolean[][] visited = new boolean[n][m];
        int res = 0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(!visited[i][j] && graph[i][j]==1){
                    visited[i][j]=true;
                    res++; 
                    dfs(visited, graph, i, j);
                }
            }
        }
        System.out.println(res);
     }
}

广度优先遍历需要定义一个队列,注意每把一个Pair加入队列时,都要立马让visited标记为true,避免重复遍历

java 复制代码
import java.util.*;

public class Main{
    public static int[][] dir = {{0,-1}, {0,1}, {-1,0}, {1,0}};

    public static class Pair{ //定义一个Pair类
        int first;
        int second;

        public Pair(int x, int y){
            this.first = x;
            this.second = y;
        }
    }

    public static void bfs(boolean[][] visited, int[][] graph, int x, int y){
        Queue<Pair> que = new LinkedList<>();
        que.offer(new Pair(x,y));
        visited[x][y] = true;//入队就直接标记为访问过
        while(!que.isEmpty()){
            int curX = que.peek().first;
            int curY = que.poll().second; //出队
            for(int i=0;i<4;i++){
                int nextX = curX+dir[i][0];
                int nextY = curY+dir[i][1];
                if(nextX<0 || nextY<0 || nextX>=graph.length || nextY>=graph[0].length) continue; //超出图的部分直接跳出循环
                if(!visited[nextX][nextY] && graph[nextX][nextY]==1){
                    que.offer(new Pair(nextX, nextY));
                    visited[nextX][nextY] = true;
                }
            }
        }
    }

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[][] graph = new int[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                graph[i][j] = sc.nextInt();
            }
        }
        boolean[][] visited = new boolean[n][m];
        int res = 0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(!visited[i][j] && graph[i][j]==1){
                    res++; 
                    bfs(visited, graph, i, j);
                }
            }
        }
        System.out.println(res);
     }
}
相关推荐
lsswear7 分钟前
Agent 框架新手入门与实战部署指南
大数据·人工智能·算法
Data analyse4562 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
Navigator_Z3 小时前
LeetCode //C - 1293. Shortest Path in a Grid with Obstacles Elimination
c语言·算法·leetcode
Nil2084 小时前
leetcode 64最小路径和
算法·leetcode·职场和发展
光影少年4 小时前
AI Agent、自动化与未来工作
人工智能·算法·架构
牧羊人.3334 小时前
计算机视觉基础 第16章|EigenFace,FisherFace,LBPH传统人脸识别算法
人工智能·算法·计算机视觉
Nil2084 小时前
leetcode 72编辑距离
算法·leetcode·职场和发展
神工坊4 小时前
技术分享︱SIMFORGE HSF® 网格加密与热点加速技术实践
算法·hpc·网格·cae·工程仿真·数值引擎·samr
CV@CV5 小时前
世界模型与智能体协同推理逻辑
人工智能·算法·边缘计算·量子计算·具身智能
jiayoushijie-泽宣5 小时前
SHIFT-PathFormer:专家轨迹蒸馏、连续安全优化与超大迷宫实验
算法