图论2(DFS和BFS相关问题)
一,寻路问题
1,迷宫
问题描述
有一迷宫,从起点1,1到终点4,3,输出所有走的路径和最短路径长度
-
边界0
-
空地1
-
障碍物2
样例输入
5 4 1 1 2 1 1 1 1 1 1 1 2 1 1 2 1 1 1 1 1 2 1 1 4 3
5代表5行,4代表4列,下面每个数字代表迷宫每个格子是边界还是空地还是障碍物
思路分析(BFS,DFS)
BFS(只输出了最短路径和最短路径长度)
package BFS; //------------------------------------------------------------------ // 迷宫问题 //------------------------------------------------------------------ // 起点1,1 // 终点4,3 //------------------------------------------------------------------ // 5行4列 //------------------------------------------------------------------ // 边界0,空地1,障碍物2 //------------------------------------------------------------------ // 输入 // 5 4 // 1 1 2 1 // 1 1 1 1 // 1 1 2 1 // 1 2 1 1 // 1 1 1 2 // 1 1 4 3 import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { public static Queue<GZ> queue = new LinkedList<GZ>(); public static int xp[] = {0, 1, 0, -1}; public static int yp[] = {1, 0, -1, 0}; public static void main(String[] args) { Scanner s = new Scanner(System.in); int m = s.nextInt(); int n = s.nextInt(); int arr[][] = new int[m + 1][n + 1]; int vic[][] = new int[m + 1][n + 1]; int p = 4, q = 3; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { arr[i][j] = s.nextInt(); } } StringBuilder lj = new StringBuilder(); lj.append("(1,1)->"); GZ gz = new GZ(1, 1, 0, lj); vic[1][1] = 1; queue.offer(gz); while (queue.peek() != null) { GZ g = queue.poll(); if (g.x == p && g.y == q) { System.out.println(); System.out.println(g.step); String substring = g.lj.toString().substring(0, g.lj.length() - 2); System.out.println(substring); break; } for (int i = 0; i < 4; i++) { int a = g.x + xp[i]; int b = g.y + yp[i]; //排除越界 if (a <= 0 || b <= 0 || a > m || b > n) { continue; } //空白格子且未访问 if (arr[a][b] == 1 && vic[a][b] == 0) { vic[a][b] = 1; String ljd = g.lj.toString(); StringBuilder ljds = new StringBuilder(ljd); ljds.append("(").append(a).append(",").append(b).append(")->"); queue.add(new GZ(a, b, g.step + 1, ljds)); } } } } } class GZ { int x; int y; int step; StringBuilder lj; public GZ(int x, int y, int step, StringBuilder lj) { this.x = x; this.y = y; this.step = step; this.lj = lj; } public GZ() { } }
DFS
package DFS; import java.util.Scanner; //------------------------------------------------------------------ // 迷宫问题 //------------------------------------------------------------------ // 起点1,1 // 终点4,3 //------------------------------------------------------------------ // 5行4列 //------------------------------------------------------------------ // 边界0,空地1,障碍物2 //------------------------------------------------------------------ // 输入 // 5 4 // 1 1 2 1 // 1 1 1 1 // 1 1 2 1 // 1 2 1 1 // 1 1 1 2 // 1 1 4 3 public class Main { //终点行坐标 public static int p; //终点列坐标 public static int q; //顺时针寻找,横纵偏移 public static int xp[] = {0, 1, 0, -1}; public static int yp[] = {1, 0, -1, 0}; //最小步数 public static int min = -1; // public static int arr[][]; public static int vic[][]; public static int m; public static int n; public static void main(String[] args) { Scanner s = new Scanner(System.in); //1.设置迷宫大小 m = s.nextInt(); n = s.nextInt(); //2.填充迷宫 arr = new int[m+1][n+1]; vic = new int[m+1][n+1]; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { arr[i][j] = s.nextInt(); } } //3.起点1,1,终点4,3 p = 4; q = 3; //4.dfs int x = 1; int y = 1; StringBuilder lj=new StringBuilder(); lj.append("(").append(x).append(",").append(y).append(")->"); dfs(x, y, 0,lj); System.out.println(min); } private static void dfs(int x, int y, int step,StringBuilder lj) { if (x == p && y == q) { String substring = lj.substring(0, lj.length() - 2); System.out.println(substring.toString()); if (min == -1 || min > step) { min = step; } return; } for (int i = 0; i < 4; i++) { int a,b; a = x + xp[i]; b = y + yp[i]; //越界跳过 if(a>m||b>n||a<=0||b<=0){ continue; } if (arr[a][b] == 1 && vic[a][b] == 0) { lj.append("(").append(a).append(",").append(b).append(")->"); vic[a][b] = 1; dfs(a, b, step + 1,lj); vic[a][b] = 0; } } } }
问题描述
给你一个大小为 m x n
的二进制矩阵 grid
。
岛屿 是由一些相邻的 1
(代表土地) 构成的组合,这里的「相邻」要求两个 1
必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid
的四个边缘都被 0
(代表水)包围着。
岛屿的面积是岛上值为 1
的单元格的数目。
计算并返回 grid
中最大的岛屿面积。如果没有岛屿,则返回面积为 0
。
示例 1:
输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]] 输出:6 解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1 。
示例 2:
输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0
提示:
-
m == grid.length
-
n == grid[i].length
-
1 <= m, n <= 50
-
grid[i][j]
为0
或1
class Solution { public int count = 0; public int[] xp = { 0, 1, 0, -1 }; public int[] yp = { 1,0 , -1, 0 }; public int maxAreaOfIsland(int[][] grid) { int max = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { if (grid[i][j] == 1) { dfs(i, j, grid); max = Math.max(max, count); count = 0; } } } return max; } private void dfs(int x, int y, int[][] grid) { grid[x][y] = 0; count++; // TODO Auto-generated method stub for (int i = 0; i < 4; i++) { int xd = x + xp[i]; int yd = y + yp[i]; if (xd < 0 || yd < 0 || xd >= grid.length || yd >= grid[0].length) { continue; } if (grid[xd][yd] == 1) { dfs(xd, yd, grid); } } } }
参考链接:https://leetcode-cn.com/problems/max-area-of-island/submissions/
3.,岛屿数量
问题描述
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] 输出:1 示例 2:
输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] 输出:3
提示:
-
m == grid.length
-
n == grid[i].length
-
1 <= m, n <= 300
-
grid
思路分析
代码实现
BFS
class Solution { // //0没有访问,1访问过 // public static int vic[][]; public static int xp[]= {0,1,0,-1}; public static int yp[]= {1,0,-1,0}; public int numIslands(char[][] grid) { int number=0; for(int i=0;i<grid.length;i++) { for(int j=0;j<grid[0].length;j++) { if(grid[i][j]=='1') { number++; bfs(i,j,grid); } } } return number; } private void bfs(int x, int y, char[][] grid) { // TODO Auto-generated method stub Queue<GZ>queue=new LinkedList<>(); queue.offer(new GZ(x,y)); GZ gz=null; while((gz=queue.poll())!=null) { for(int i=0;i<4;i++) { int xd=gz.x+xp[i]; int yd=gz.y+yp[i]; if(xd<0||xd>=grid.length||yd<0||yd>=grid[0].length) { continue; } if(grid[xd][yd]!='0') { grid[xd][yd]='0'; queue.offer(new GZ(xd,yd)); } } } } } class GZ{ public int x; public int y; public GZ(int x,int y) { this.x=x; this.y=y; } public GZ() { } }
DFS
class Solution { public static int xp[]= {0,1,0,-1}; public static int yp[]= {1,0,-1,0}; public int numIslands(char[][] grid) { int number=0; for(int i=0;i<grid.length;i++) { for(int j=0;j<grid[0].length;j++) { if(grid[i][j]=='1') { number++; dfs(i,j,grid); } } } return number; } private void dfs(int x, int y,char[][]grid) { for(int i=0;i<4;i++) { int xd=x+xp[i]; int yd=y+yp[i]; if(xd<0||xd>=grid.length||yd<0||yd>=grid[0].length) { continue; } if(grid[xd][yd]!='0') { grid[xd][yd]='0'; dfs(xd, yd, grid); } } } }
参考链接:https://leetcode-cn.com/problems/number-of-islands
4,岛屿周长
问题描述
给定一个 row x col 的二维网格地图 grid ,其中:grid
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
示例 1:
输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]] 输出:16 解释:它的周长是上面图片中的 16 个黄色的边 示例 2:
输入:grid = [[1]] 输出:4 示例 3:
输入:grid = [[1,0]] 输出:4
提示:
-
row == grid.length
-
col == grid[i].length
-
1 <= row, col <= 100
-
grid
思路分析
代码实现
DFS
class Solution { public int[][] grid; public int[][] vic; public int xp[]= {0,1,0,-1}; public int yp[]= {1,0,-1,0}; public int len=0; public int islandPerimeter(int[][] grid) { this.grid=grid; vic=new int[grid.length][grid[0].length]; for(int i=0;i<grid.length;i++) { for(int j=0;j<grid[0].length;j++) { if(grid[i][j]==1&&vic[i][j]==0) { vic[i][j]=1; dfs(i,j); //只有一个岛屿,找到就break break; } } } return len; } private int dfs(int x, int y) { // TODO Auto-generated method stub for(int i=0;i<4;i++) { int xd=x+xp[i]; int yd=y+yp[i]; if(xd<0||yd<0||xd>=grid.length||yd>=grid[0].length||grid[xd][yd]==0) { len+=1; continue; } if(vic[xd][yd]==1) { continue; } vic[xd][yd]=1; dfs(xd, yd); } return len; } }
参考链接:https://leetcode-cn.com/problems/island-perimeter
5,方格分割
6x6的方格,沿着格子的边线剪开成两部分。 要求这两部分的形状完全相同。
如下就是三种可行的分割法。
思路分析
代码实现
package fgfg; public class Main { public static int[] xp = { 0, 1, 0, -1 }; public static int[] yp = { 1, 0, -1, 0 }; public static int[][] vic = new int[7][7]; public static int count = 0; public static void main(String[] args) { vic[3][3] = 1; dfs(3, 3); System.out.println(count/4); } public static void dfs(int x, int y) { for (int i = 0; i < 4; i++) { int xd = x + xp[i]; int yd = y + yp[i]; if (xd <= 0 || yd <= 0 || xd >= 6 || yd >= 6) { count++; continue; } if (vic[xd][yd] == 0) { vic[xd][yd] =vic[6-xd][6-yd]= 1; dfs(xd, yd); vic[xd][yd]= vic[6-xd][6-yd]= 0; } } } }
参考链接:https://www.lanqiao.cn/problems/1629/learning/?is_contest=true
二,找数问题
1,找满足条件的四个数(排列组合)
问题描述
给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。 例如: 3 1 2 4 4 3 6 7 9 16 现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。 输入 4 16 输出 3 1 2 4
思路分析(BFS,DFS)
代码实现
BFS
package BFS; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; // 给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。 // 例如: // 3 1 2 4 // 4 3 6 // 7 9 // 16 // 现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。 //输入 //4 16 //输出 //3 1 2 4 public class Main2 { public static Queue<SZ> queue = new LinkedList<>(); public static void main(String[] args) { Scanner s = new Scanner(System.in); int n = s.nextInt(); int sum = s.nextInt(); for (int i = 0; i < n; i++) { int arr[] = new int[n]; int step = 0; arr[step] = i + 1; SZ sz = new SZ(arr, step); sz.vic[i] = 0; queue.offer(sz); } while (queue.peek() != null) { SZ sz = queue.poll(); if (sz.step == 3) { int[] arr=sz.arr; int[] arr1=Arrays.copyOf(arr,arr.length); for(int i=1;i<n;i++){ for(int j=0;j<n-i;j++){ arr1[j]=arr1[j]+arr1[j+1]; } } if(arr1[0]==sum){ StringBuilder str=new StringBuilder(); for(int i=0;i<n;i++){ str.append(arr[i]).append(" "); } System.out.println(str.toString()); break; } continue; } for (int i = 0; i < n; i++) { if (sz.vic[i] != 0) { int[] arr = Arrays.copyOf(sz.arr,sz.arr.length); int step=sz.step+1; arr[step] = sz.vic[i]; SZ szt = new SZ(arr, step); szt.vic=Arrays.copyOf(sz.vic,sz.vic.length); szt.vic[i] = 0; queue.offer(szt); } } } } static class SZ { int arr[]; int vic[] = {1, 2, 3, 4}; int step; public SZ() { } public SZ(int arr[], int step) { this.step = step; this.arr = arr; } } }
DFS
package DFS; import java.util.Arrays; import java.util.Scanner; // 给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。 // 例如: // 3 1 2 4 // 4 3 6 // 7 9 // 16 // 现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。 //输入 //4 16 //输出 //3 1 2 4 public class Main2 { public static Boolean flag=true; public static int n; public static int sum; public static int vic[]; public static void main(String[] args) { Scanner s=new Scanner(System.in); n = s.nextInt(); sum=s.nextInt(); vic=new int[n+1]; int arr[]=new int[n]; dfs(arr,0); } private static void dfs(int[] arr, int step) { if (step == n) { int[] arr1= Arrays.copyOf(arr,arr.length); for(int i=1;i<n;i++){ for(int j=0;j<n-i;j++){ arr1[j]=arr1[j]+arr1[j+1]; } } if(arr1[0]==sum){ flag=false; StringBuilder str=new StringBuilder(); for(int a:arr){ str.append(a).append(" "); } System.out.println(str.toString()); } return; } if (flag) { for (int i = 1; i <= n; i++) { int t = i; if (vic[i] == 0) { arr[step] = i; vic[i] = 1; dfs(arr, step + 1); vic[i] = 0; } } } } }
2.输出子集
问题描述
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 示例 2:
输入:nums = [0] 输出:[[],[0]]
提示:
-
1 <= nums.length <= 10
-
-10 <= nums[i] <= 10
-
nums 中的所有元素 互不相同
思路分析
代码实现
class Solution { public int[] nums; public List<List<Integer>> list; public List<List<Integer>> subsets(int[] nums) { this.nums = nums; list = new ArrayList<List<Integer>>(); list.add(new ArrayList<>()); for (int i = 0; i < nums.length; i++) { for (int j = 1; j <=nums.length; j++) { Integer[]num=new Integer[j]; dfs(i, j, 1, num); } } return list; } private void dfs(int begin, int number, int step, Integer[]num) { // TODO Auto-generated method stub num[step-1]=nums[begin]; if (step == number) { List<Integer>list2=new ArrayList<>(); for(int i=0;i<num.length;i++) { list2.add(num[i]); } list.add(list2); return; } for (int i = begin + 1; i < nums.length; i++) { dfs(i, number, step + 1, num); } } }
3,等差素数列
2,3,5,7,11,13,.... 是素数序列。 类似:7,37,67,97,127,1577,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列。
上边的数列公差为 3030,长度为 66。
20042004 年,格林与华人陶哲轩合作证明了:存在任意长度的素数等差数列。 这是数论领域一项惊人的成果!
有这一理论为基础,请你借助手中的计算机,满怀信心地搜索:
长度为 1010 的等差素数列,其公差最小值是多少?
思路分析
代码实现
package susc; import java.util.ArrayList; import java.util.List; //长度为 1010 的等差素数列,其公差最小值是多少? public class Main { public static List<Integer> list = new ArrayList<>(); public static void main(String[] args) { // 添加到10000的素数 for (int i = 2; i < 10000; i++) { if (isSuShu(i)) { list.add(i); } } for (int i = 0; i < list.size(); i++) { for (int j = 1; j < 1000; j++) { dfs(i, j, list.get(i), 1); } } } private static Boolean dfs(int begin, int dc, Integer lastShu, int step) { // TODO Auto-generated method stub if (step == 10) { System.out.println(dc); return true; } for (int i = begin + 1; i < list.size(); i++) { Integer shu = list.get(i); if ((shu - lastShu) == dc) { dfs(i, dc, shu, step + 1); } if ((shu - lastShu) > dc) { return false; } } return false; } public static Boolean isSuShu(int shu) { Boolean flag = true; if (shu < 2) { flag = false; } for (int i = 2; i <= Math.sqrt(shu); i++) { if (shu % i == 0) { flag = false; } } return flag; } }
问题描述
下图转自“英式没品笑话百科”的新浪微博 —— 所以无论有没有遇到难题,其实都不用担心。
输入格式
输入首先在一行中给出两个正整数 N(1<N≤500)和 M,分别为命题个数和推理个数。这里我们假设命题从 1 到 N 编号。
接下来 M 行,每行给出一对命题之间的推理关系,即两个命题的编号 S1 S2
,表示可以从 S1
推出 S2
。题目保证任意两命题之间只存在最多一种推理关系,且任一命题不能循环自证(即从该命题出发推出该命题自己)。
最后一行给出待检验的两个命题的编号 A B
。
输出格式
在一行中首先输出从 A
到 B
有多少种不同的推理路径,然后输出 Yes
如果推理是“逻辑自洽”的,或 No
如果不是。
题目保证输出数据不超过 109。
输入样例1
7 8 7 6 7 4 6 5 4 1 5 2 5 3 2 1 3 1 7 1
3 Yes
7 8 7 6 7 4 6 5 4 1 5 2 5 3 6 1 3 1 7 1
3 No
思路分析
这题的大意是从A到B有多少条路径,从A出发,可能有多条路径,但最后的终点必须是B,要不然就不是逻辑自洽了,由于是有向无环图,不用考虑从A到B再到A的循环情况,所以可以不用vic
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class Main { public Boolean flag = true; public int[] dot = null; public static Map<Integer, List<Integer>> map = new HashMap<>(); public static void main(String[] args) { Scanner sca = new Scanner(System.in); int n = sca.nextInt(); int m = sca.nextInt(); Main main = new Main(); main.dot = new int[n + 1]; for (int i = 0; i < main.dot.length; i++) { main.dot[i] = -1; } // 有向无环图,邻接表 for (int i = 0; i < m; i++) { Integer start = sca.nextInt(); Integer end = sca.nextInt(); List<Integer> list = map.getOrDefault(start, new ArrayList<>()); list.add(end); map.put(start, list); } int startQ = sca.nextInt(); int endQ = sca.nextInt(); int result = main.dfs(startQ, endQ); String str = main.flag == true ? "Yes" : "No"; System.out.println(result + " " + str); } private int dfs(int startQ, int endQ) { // TODO Auto-generated method stub int result = 0; if (dot[startQ] != -1) { return dot[startQ]; } if (startQ == endQ) { return 1; } List<Integer> list = map.get(startQ); if (list == null) { flag = false; return dot[startQ] = 0; } for (Integer d : list) { result += dfs(d, endQ); } return dot[startQ] = result; } }
题目描述
问题描述 抗日战争时期,冀中平原的地道战曾发挥重要作用。 地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。 我们来定义一个危险系数DF(x,y): 对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。
输入
输入数据第一行包含2个整数n(2 < = n < = 1000), m(0 < = m < = 2000),分别代表站点数,通道数; 接下来m行,每行两个整数 u,v (1 < = u, v < = n; u != v)代表一条通道; 最后1行,两个数u,v,代表询问两点之间的危险系数DF(u, v)。
输出
一个整数,如果询问的两点不连通则输出-1.
样例输入
7 6 1 3 2 3 3 4 3 5 4 5 5 6 1 6
思路分析
询问通道是否连通,也就是能走到就true,不能走到就false
关键点,也就是起点到终点无论怎么走也必须经过的点,转换一下,
假如起点到终点有t条路径,也就是说必定经过关键点t次(除起点和终点)
也就是说从起点到终点,经过t次的点就是我们要找的点(除起点和终点)
package DayT2; import java.util.Scanner; public class Main { // 记录顶点个数 public int n; // 记录通道连通情况 public int[][] arr = null; // 记录终点 public int endQ = -1; // 记录能否到终点 public Boolean flag = false; // 记录从起点到终点不同路径下每个点经过的次数(不算起点) public int[] dot = null; // dfs的vic public int[] vic = null; public static void main(String[] args) { Scanner sca = new Scanner(System.in); Main main = new Main(); //接收顶点数和边数 main.n = sca.nextInt(); int m = sca.nextInt(); main.init(); //由于是无向图,所以构建邻接矩阵 for (int i = 0; i < m; i++) { int start = sca.nextInt(); int end = sca.nextInt(); // 站点x和y连通,也就是说能从x到y,也能从y到x main.arr[start][end] = main.arr[end][start] = 1; } //接收起点,终点 int startQ = sca.nextInt(); main.endQ = sca.nextInt(); //dfs int result = main.dfs(startQ, 0, new int[main.n + 1]); int count = 0; //如果两个点不连通,输出-1 if(main.flag==false) { System.out.println(-1); } //记录有多少个点是去终点的必经之点 for (int i = 1; i < main.n + 1; i++) { if (main.dot[i] == result) { count++; } } // 减去终点 System.out.println(count - 1); } private void init() { // TODO Auto-generated method stub arr = new int[n + 1][n + 1]; dot = new int[n + 1]; vic = new int[n + 1]; } /** * * @param startQ:到达的点 * @param step:第几个经过点,0代表起点 * @param temp:从起点到终点经过的点的数组 * @return */ private int dfs(int startQ, int step, int[] temp) { // TODO Auto-generated method stub //如果到达的点为终点,说明已经到了终点,有一条路径了 if (startQ == endQ) { //将从起点到终点经过点的次数加一 for (int i = 0; i < step; i++) { dot[temp[i]]++; } flag = true; return 1; } int result = 0; //遍历该点能到的点 for (int i = 1; i < n + 1; i++) { //如果访问过,continue if (vic[i] == 1) { continue; } //如果不连通,continue if (arr[startQ][i] == 0) { continue; } //记录经过的点 temp[step] = i; //dfs vic[i] = 1; result += dfs(i, step + 1, temp); vic[i] = 0; } //返回从startQ到终点路径条数 return result; } }
题目链接:https://www.dotcpp.com/oj/problem1433.html
本文来自博客园,作者:lzstar-A2,转载请注明原文链接:https://www.cnblogs.com/lzstar/p/15399235.html
作 者:lzstar-A2
出 处:https://www.cnblogs.com/lzstar/
关于作者:一名java转安全的在校大学生
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎大家关注安全学习交流群菜鸟联盟(IThonest),如果您觉得文章对您有很大的帮助,您可以考虑赏博主一杯可乐以资鼓励,您的肯定将是我最大的动力。thx.
菜鸟联盟(IThonest),一个可能会有故事的qq群,欢迎大家来这里讨论,共同进步,不断学习才能不断进步。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码),个人QQ和微信的二维码也已给出,扫描下面👇的二维码一起来讨论吧!!!