求无向图中任意两点间所有路径.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、回溯法 适用不断分支 找出所有分支
2、树的路径(路径的值为某定值):先根遍历+栈式容器(存储路径节点)
3、图的路径 一般使用回溯法+栈(存储路径节点)+访问标记数组:先达到终点 按访问标记数组 弹出栈顶元素
4、回溯法 适用不断分支 找出所有分支