华为笔试5.20有向图环路—Java

有向图寻找环路(图+dfs)
如有错误,欢迎指出
edges记录邻接矩阵
使用used数组记录当前节点是否被使用过
使用instack数组记录目前节点是否在搜索路径中
stack记录搜索路径
题目描述
给定一个有向图,假定最多10个节点,节点编号依次为A~J,如果A节点到B节点之间有通路则描述为A->B,多条边的描述之间以分号隔开,给定一个有向图,求该有向图中的所有环路,环路以节点编号的最小的节点开始输出,假定一个有向图最多一个环路,如果没有环路则输出空字符串“-”。输入为连接链表。
输入描述:
输入为连接链表字符串,如 :A->B;B->D;C->B;C->E;D->C
输出描述:
环路节点组成的字符串,如:输出字符串BDC,标识B->D->C->B组成环路
示例1输入输出示例仅供调试,后台判题数据一般不包含示例
输入
A->B;B->D;C->B;C->E;D->C
输出
BDC

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

public class Two {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = in.next();
        // 检查输入合法性
        boolean matches = str.matches("[A-J]\\-\\>[A-J](\\;[A-J]\\-\\>[A-J]){0,9}");
        if (matches) {
            String[] paths = str.split(";");
            // 创建邻接矩阵
            int[][] edges = new int[paths.length][paths.length];
            for (String path : paths) {
                String[] bet = path.split("->");
                int u = bet[0].charAt(0) - 'A';
                int v = bet[1].charAt(0) - 'A';
                edges[u][v] = 1;
            }
            // 定义数组boolean[],记录结点是否被访问
            boolean[] used = new boolean[edges.length];
            List<Integer> cycle = new ArrayList<Integer>();
            helper(edges, cycle);
            if(cycle.size()==0) {
                System.out.println("-");
                return;
            }
            for (Integer integer : cycle) {
                System.out.print((char)('A'+integer));
            }
        } else {
            System.out.println("-");
            return;
        }
        in.close();
    }

    private static void helper(int[][] edges, List<Integer> cycle) {
        // TODO Auto-generated method stub
        boolean[] used = new boolean[edges.length];
        boolean[] instack = new boolean[edges.length];
        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < used.length; i++) {
            if (!used[i]) {
                dfs(i, used, instack, stack, cycle, edges);
            }
        }
    }

    private static void dfs(int i, boolean[] used, boolean[] instack, Stack<Integer> stack, List<Integer> cycle,
            int[][] edges) {
        // TODO Auto-generated method stub
        used[i] = true;
        if (instack[i]) {
            int count = stack.indexOf(i);
            Stack<Integer> tem = new Stack<Integer>();
            tem.addAll(stack);
            while (tem.size() > count) {
                cycle.add(tem.pop());
            }
            Collections.reverse(cycle);
            return;
        }
        instack[i] = true;
        stack.push(i);
        for (int j = 0; j < edges[i].length; j++) {
            if(edges[i][j]!=1)
                continue;
            dfs(j, used, instack, stack, cycle, edges);
        }
        // 回溯
        stack.pop();
        instack[i] = false;
    }

}
全部评论

相关推荐

1 4 评论
分享
牛客网
牛客企业服务