判断图的环

1.DFS判断有向图或者无欢图有没有环

public class Main { 
    static class point{
        int x;
        int y;
        int len;
        public point(int x, int y,int len) {
            this.x = x;
            this.y = y;
        }     
    }
    boolean flag=false;
    public static void main(String[] args) {         
          Scanner sc=new Scanner(System.in);
          Main s=new Main();
          int n=sc.nextInt();
          int[][] a=new int[n+1][n+1];
          for(int i=0;i<n;i++) {
              int left=sc.nextInt();
              int right=sc.nextInt();
              a[left][right]=1;
              a[right][left]=1;//加这个是无环图
          } 
          int[] vis=new int[n+1];
          s.dfs(1,0,vis,a);
          System.out.println(s.flag);
    }   
    public void dfs(int cur,int pre,int[] vis,int[][] grids)//dfs判无向环
    {
        vis[cur] = 1;
        if(flag) return;
        for(int i = 1; i < grids.length; i++)
        {
            if(grids[cur][i]==1) {//表示可以走
                if(vis[i]==0) {
                    dfs(i,cur,vis,grids);
                }
                else if(i!=pre)//这个点已经走过了,排除又指回去,就是pre,这个一般是没有方向的。有方向的话是不用加这个判断的,因为本身指回去也是一个环
                {
                    flag=true;//就说明存在环
                }
            }
        }
        vis[cur] = 0;
    } 
}

2.用拓扑排序判断有向图是否存在回路(每次去掉入度为0的节点,直到任何一个节点入度都是0,那么这个有向图就是无环的)

//带入度的领接表结构
    static class Graph{
        ArrayList<Vertex> vertexList=new ArrayList<Vertex>();
        int vertexNum=0;
        int edgeNum=0;
        public Graph(){}
        //
        public static class Edge {
            int val;//边的后面的节点
            Edge next;
        }
        //
        public static class Vertex {
            int count;//用来标识这个点的入度
            int val;//用来标识这个点的
            Edge firstEdge=new Edge();
        }
    }
    public boolean ExistCycle(Graph G) {
        Stack<Integer> stack=new Stack<>();
        Edge p;
        int res=0;//用这个数来记录出栈的个数
        for(int i=0;i<G.vertexNum;i++) {
            if(G.vertexList.get(i).count==0) {//入度为0的入栈
                stack.push(G.vertexList.get(i).val);
            }
            while(!stack.isEmpty()) {
                int j=stack.pop();
                res++;
                p=vertexList.get(j).firstEdge;//找到第一个邻接边
                while(p!=null) {
                    int temp=p.val;//获取这条边后面这个节点
                    G.vertexList.get(temp).count--;
                    if(G.vertexList.get(temp).count==0) {
                        stack.push(temp);
                    }
                    p=p.next;
                }
            }
        }
        if(res<G.vertexNum)
            return false;
        else
            return true;
    }

 3.求无环图最长路径

public class Main { 
    int sum;
    public static void main(String[] args) {         
          Scanner sc=new Scanner(System.in);
          Main s=new Main();
          int n=sc.nextInt();
          int[][] a=new int[n+1][n+1];
          int[] vis=new int[n+1];
          for(int i=0;i<n-1;i++) {
              int left=sc.nextInt();
              int right=sc.nextInt();
              a[left][right]=1;
              a[right][left]=1;
          } 
          s.dfs(1,0,a,vis);
          System.out.println(s.sum+2*(n-s.sum-1));
    }   
    public void dfs(int cur,int w,int[][] grids,int[] vis)//dfs判无向环
    {
        vis[cur]=1;
        for(int i = 1; i < grids.length; i++)
        {
            if(grids[cur][i]==1) {//表示可以走
                if(vis[i]==0) {   //还没有走过
                    dfs(i,w+1,grids,vis);
                }
            }
            sum=Math.max(sum, w);
        }
        vis[cur]=0;        
    } 
}

 

posted @ 2019-08-28 15:37  LeeJuly  阅读(374)  评论(0)    收藏  举报