zoukankan      html  css  js  c++  java
  • 算法笔记_147:有向图欧拉回路判断应用(Java)

    目录

    1 问题描述

    2 解决方案

     


    1 问题描述

    Description

    In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

    Input

    The first line contains a single integer T, the number of test cases. And followed T cases. 

    The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly. 

    Output

    The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.

    Sample Input

    1
    3 3
    1 2
    2 3
    3 1
    

    Sample Output

    Yes

    Source

     

    2 解决方案

    具体代码如下:

    package com.liuzhen.practice;
    
    import java.util.ArrayList;
    import java.util.Scanner;
    import java.util.Stack;
    
    public class Main {
        public static int n;  //顶点数
        public static int count;
        public static int[] DFN;
        public static int[] Low;
        public static boolean[] inStack;
        public static int group;  //强连通分量组
        public static int[] belong;
        public static Stack<Integer> stack;
        public static ArrayList<edge>[] map;
        public static ArrayList<String> result = new ArrayList<String>();
        
        static class edge {
            public int a;
            public int b;
            
            public edge(int a, int b) {
                this.a = a;
                this.b = b;
            }
        }
        
        @SuppressWarnings("unchecked")
        public void init() {
            count = 1;
            DFN = new int[n + 1];
            Low = new int[n + 1];
            inStack = new boolean[n + 1];
            group = 0;
            belong = new int[n + 1];
            stack = new Stack<Integer>();
            map = new ArrayList[n + 1];
            for(int i = 1;i <= n;i++) {
                DFN[i] = -1;
                Low[i] = -1;
                inStack[i] = false;
                belong[i] = -1;
                map[i] = new ArrayList<edge>();
            }
        }
        
        public void TarJan(int start) {
            DFN[start] = count++;
            Low[start] = DFN[start];
            inStack[start] = true;
            stack.push(start);
            int j = start;
            for(int i = 0;i < map[start].size();i++) {
                j = map[start].get(i).b;
                if(DFN[j] == -1) {
                    TarJan(j);
                    Low[start] = Math.min(Low[start], Low[j]);
                } else if(inStack[j]) {
                    Low[start] = Math.min(Low[start], DFN[j]);
                }
            }
            if(DFN[start] == Low[start]) {
                group++;
                do {
                    j = stack.pop();
                    belong[j] = group;
                    inStack[j] = false;
                } while(j != start);
            }
        }
        
        public boolean TopSort(ArrayList<edge>[] lessMap, int[] degree) {
            int count = 0;
            Stack<Integer> s = new Stack<Integer>();
            for(int i = 1;i < degree.length;i++) {
                if(degree[i] == 0) {
                    count++;
                    s.push(i);
                }
            }
            if(count > 1)
                return false;
            while(!s.empty()) {
                int start = s.pop();
                count = 0;
                for(int i = 0;i < lessMap[start].size();i++) {
                    int j = lessMap[start].get(i).b;
                    degree[j]--;
                    if(degree[j] == 0) {
                        count++;
                        s.push(j);
                    }
                }
                if(count > 1)
                    return false;
            }
            return true;
        }
        
        @SuppressWarnings("unchecked")
        public void getResult() {
            for(int i = 1;i <= n;i++) {
                if(DFN[i] == -1)
                    TarJan(i);
            }
            ArrayList<edge>[] lessMap = new ArrayList[group + 1];
            int[] degree = new int[group + 1];
            for(int i = 1;i <= group;i++)
                lessMap[i] = new ArrayList<edge>();
            for(int i = 1;i < map.length;i++) {
                for(int j = 0;j < map[i].size();j++) {
                    int a = map[i].get(j).a;
                    int b = map[i].get(j).b;
                    if(belong[a] != belong [b]) {
                        lessMap[belong[a]].add(new edge(belong[a], belong[b]));
                        degree[belong[b]]++;
                    }
                }
            }
            if(TopSort(lessMap, degree)) {
                result.add("Yes");
            } else {
                result.add("No");
            }
            return;
        }
        
        public static void main(String[] args) {
            Main test = new Main();
            Scanner in = new Scanner(System.in);
            int t = in.nextInt();
            while(t > 0) {
                t--;
                n = in.nextInt();
                int k = in.nextInt();
                test.init();
                for(int i = 0;i < k;i++) {
                    int a = in.nextInt();
                    int b = in.nextInt();
                    map[a].add(new edge(a, b));
                }
                test.getResult();
            }
            for(int i = 0;i < result.size();i++)
                System.out.println(result.get(i));
        }
    }

    运行结果:

    1
    3 3
    1 2
    2 3
    3 1
    Yes

     

     

     

     

    参考资料:

       1. 欧拉回路

        2. POJ2762 Going from u to v or from v to u?(强连通分量缩点+拓扑排序)

  • 相关阅读:
    织梦标签调用:根据特定需求调用文章的标签代码
    织梦DedeCMS信息发布员发布文章阅读权限不用审核自动开放亲测试通过!
    javascript中的this和e.target的深入研究
    vue-cli入门(二)——项目结构
    Mysql千万级大数据量查询优化
    MySQL大数据量分页查询方法及其优化
    Spring Bean的生命周期分析
    多线程下,两个线程交替打印0 -100,使用wait()和notify()
    ReentrantLock
    多线程交替打印ABC的多种实现方法
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/6767669.html
Copyright © 2011-2022 走看看