zoukankan      html  css  js  c++  java
  • Java实现判断单联通(强连通缩点+拓扑排序)Going from u to v or from v to u

    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

    中文说明

    为了让他们的儿子勇敢,嘉嘉和风把他们带到一个大山洞。这个洞穴有N个房间,还有连接一些房间的单向走廊。每次,风都会选择两个房间x和y,并要求他们的一个小儿子从一个房间到另一个房间。儿子可以从X到Y,也可以从Y到X。Wind承诺她的任务都是可能的,但实际上她不知道如何决定任务是否可能。为了让她的生活更轻松,贾佳决定选择一个洞穴,在那里每对房间都是一个可能的任务。给定一个山洞,你能告诉佳佳风是否可以随意选择两个房间而不必担心什么吗?

    输入

    第一行包含一个整数t,即测试用例的数量。并跟踪T案。

    每种情况的第一行包含两个整数n,m(0<n<1001,m<6000),洞穴中房间和走廊的数量。下一条M线分别包含两个整数u和v,表示有一条走廊直接连接u和v房间。

    输出

    输出应包含T行。如果洞穴具有上述财产,则写“是”,否则写“否”。

    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));
        }
    }
    

    运行结果:

    3 3
    2
    3
    1
    Yes
    
  • 相关阅读:
    mac下 brew 切换阿里镜像
    梨视频(PearVideo)下载解析的方法和技巧,梨视频下载到本地
    如何快速的下载Tumblr(汤不热)视频?操作步骤很简单,快来看看!
    什么是json? 什么是xml?JSON与XML的区别比较
    如何下载Twitter视频?最简单的保存推特视频的方法
    【收藏】轻松导出全民K歌里任何人录制的短视频(MV)、歌曲的方法
    【小白技术笔记】保存皮皮虾APP无水印视频到手机相册,只需要三步 [技术干货]
    技术干货!腾讯微视短视频去水印下载到本地的方法
    P1562 还是N皇后
    循环赛日程表
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12947882.html
Copyright © 2011-2022 走看看