图的路径

求无向图中任意两点间所有路径.java

package com.exercise.图论.消防车;

import java.util.Scanner;
import java.util.Stack;

public class 求无向图中任意两点间所有路径 {

	/**
	 * @param args
	 * 算法思路   
		  A 将始点入栈
		  B 查看栈顶节点V在图中,有没有可以到达、且没有入栈、且没有从这个节点V出发访问过的节点
		  C 如果有,则将找到的这个节点入栈
		  D 如果没有,V出栈   并将V能到达的节点中没在栈中的节点的访问标记设为 未访问(保证无环且某两点间的路径可出现在多条路径上)
		  E 当栈顶元素为终点时,打印栈中元素,弹出栈顶节点
		  F 重复执行B – E,直到栈中元素为空
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		
		int last=scanner.nextInt();//终点
		
		int route[][]=new int[100][2];//从节点i到j的路径畅通
		
		int visited[];//访问标记
		
		for (int i = 0; i < 100; i++) {
			for (int j = 0; j < 2; j++) {
				route[i][j]=0;
			}
		}
		
		int row=0;
		while (scanner.hasNextInt()) {
			int a=scanner.nextInt();
			if (a==0) {
				break;
			}
			int b=scanner.nextInt();
			route[row][0]=a;
			route[row][1]=b;
			row++;
		}
		
		visited =new int[row+1];
		
		for (int i = 0; i < visited.length; i++) {
			visited[i]=0;
		}
		
		Stack<Integer> routeStack=new Stack<Integer>();
		
		routeStack.push(1);
		
		while(!routeStack.isEmpty()){      //F
			int first=routeStack.peek();
			if (first==last) {
				printRoute(routeStack);
				routeStack.pop();
				continue;
			}
			int next=search(route, visited, first,routeStack);
			if (next!=0) {
				routeStack.push(next);
			}else {
				setRouteBackOk(route, visited, routeStack.pop(), last,routeStack);
			}
		}

	}
	
	public  static int  search(int[][] route ,int visited[],int a,Stack<Integer> routeStack) {
		for (int i = 0; i < visited.length; i++) {
			if (route[i][0]==a&&visited[i]==0&&!routeStack.contains(route[i][1])) {
				visited[i]=1;
				return route[i][1];
			}
			if (route[i][1]==a&&visited[i]==0&&!routeStack.contains(route[i][0])) {
				visited[i]=1;
				return route[i][0];
			}
		}
		return 0;
	}
	
	public  static void printRoute(Stack<Integer> stack){
		Object[] r= stack.toArray();
		for (int i = 0; i <r.length; i++) {
			System.out.print(r[i]+" ");
		}
		System.out.println();
	}
	
	//某个顶点出栈时 设置它能到达的路线 为 未 拜访过(某两点之间的路径 可能同时出现在多条路径上)
	public  static void setRouteBackOk(int[][] route ,int visited[],int a,int last,Stack<Integer> routeStack){
		//System.out.println("pop:"+a);
		for (int i = 0; i < visited.length; i++) {
			if (route[i][0]==a&&visited[i]!=0&&!routeStack.contains(route[i][1])) {
				visited[i]=0;
			}
			if (route[i][1]==a&&visited[i]!=0&&!routeStack.contains(route[i][0])) {
				visited[i]=0;
			}
		}
	}

}
测试数据

6
1 2
1 3
3 4
3 5
4 6
5 6
2 4
2 3
0 0
4
2 3
3 4
5 1
1 6
7 8
8 9
2 5
5 7
3 1
1 8
4 6
6 9
0 0


#####
6
1 2
1 3
3 4
3 5
4 6
5 6
2 4
2 3
0 0
1 2 4 3 5 6
1 2 4 6
1 2 3 4 6
1 2 3 5 6
1 3 4 6
1 3 5 6
1 3 2 4 6

####
4
2 3
3 4
5 1
1 6
7 8
8 9
2 5
5 7
3 1
1 8
4 6
6 9
0 0
1 5 2 3 4
1 5 7 8 9 6 4
1 6 4
1 6 9 8 7 5 2 3 4
1 3 2 5 7 8 9 6 4
1 3 4
1 8 7 5 2 3 4
1 8 9 6 4 



求有向图中任意两点间所有路径.java

package com.exercise.图论.消防车;

import java.util.Scanner;
import java.util.Stack;

public class 求有向图中任意两点间所有路径 {

	/**
	 * @param args
	 * 算法思路   
		  A 将始点入栈
		  B 查看栈顶节点V在图中,有没有可以到达、且没有入栈、且没有从这个节点V出发访问过的节点
		  C 如果有,则将找到的这个节点入栈
		  D 如果没有,V出栈   并将V能到达的节点设为 未访问(某两点间的路径可出现在多条路径上)
		  E 当栈顶元素为终点时,打印栈中元素,弹出栈顶节点
		  F 重复执行B – E,直到栈中元素为空
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		
		int last=scanner.nextInt();//终点
		
		int route[][]=new int[100][2];
		
		int visited[];
		
		for (int i = 0; i < 100; i++) {
			for (int j = 0; j < 2; j++) {
				route[i][j]=0;
			}
		}
		
		int row=0;
		while (scanner.hasNextInt()) {
			int a=scanner.nextInt();
			if (a==0) {
				break;
			}
			int b=scanner.nextInt();
			route[row][0]=a;
			route[row][1]=b;
			row++;
		}
		
		visited =new int[row+1];
		
		for (int i = 0; i < visited.length; i++) {
			visited[i]=0;
		}
		
		Stack<Integer> routeStack=new Stack<Integer>();
		
		routeStack.push(1);
		
		while(!routeStack.isEmpty()){
			int first=routeStack.peek();
			//System.out.println(first);
			if (first==last) {
				printRoute(routeStack);
				routeStack.pop();
				//System.out.println("pop6:"+routeStack.pop());
				continue;
			}
			int next=search(route, visited, first);
			if (next!=0) {
				routeStack.push(next);
			}else {
				setRouteBackOk(route, visited, routeStack.pop(), last);
				//System.out.println("pop:"+routeStack.pop());
			}
		}

	}
	
	public  static int  search(int[][] route ,int visited[],int a) {
		for (int i = 0; i < visited.length; i++) {
			if (route[i][0]==a&&visited[i]==0) {
				visited[i]=1;
				return route[i][1];
			}
		}
		return 0;
	}
	
	public  static void printRoute(Stack<Integer> stack){
		Object[] r= stack.toArray();
		for (int i = 0; i <r.length; i++) {
			System.out.print(r[i]+" ");
		}
		System.out.println();
	}
	
	//某个顶点出栈时 设置它能到达的路线 为 未 拜访过(某两点之间的路径 可能同时出现在多条路径上)
	public  static void setRouteBackOk(int[][] route ,int visited[],int a,int last){
		//System.out.println("pop:"+a);
		for (int i = 0; i < visited.length; i++) {
			if (route[i][0]==a&&visited[i]!=0) {
				visited[i]=0;
			}
		}
	}

}

  • 总结
1、可以使用递归 就可以 使用 栈 来实现

2、树的路径(路径的值为某定值):先根遍历+栈式容器(存储路径节点)

3、图的路径 一般使用回溯法+栈(存储路径节点)+访问标记数组:先达到终点 按访问标记数组 弹出栈顶元素

4、回溯法 适用不断分支 找出所有分支


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值