zoukankan      html  css  js  c++  java
  • 算法笔记_143:构造无向图的欧拉回路(Java)

    目录

    1 问题描述

    2 解决方案

     


    1 问题描述

     

    具体链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=995


    2 解决方案

    具体代码如下:

     

    package com.liuzhen.practice;
    
    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class Main {
        public static int MAX = 1000;   
        public static int start, count;  
        public static int num = 0;
        public static int[] id = new int[MAX]; 
        public static int[] degree = new int[MAX];  //用于计算给定图每个顶点的度
        public static boolean[] used = new boolean[MAX];   //用于判断图中相应边是否被遍历
        public static String[] path = new String[MAX];
        public static ArrayList<String> result = new ArrayList<String>();                      
        
        static class edge {
            public int a;  //边的起点
            public int b;  //边的终点
            public int num;  //边的编号
            
            public edge(int a, int b, int num) {
                this.a = a;
                this.b = b;
                this.num = num;
            }
            
            public String getAB() {
                return a + " "+ b;
            }
        }
        //寻找顶点a的根节点
        public int find(int[] id, int a) {
            int root = a;
            while(id[root] >= 0) {
                root = id[root];
            }
            int i;
            int k = a;
            while(k != root) {
                i = id[k];
                id[k] = root;
                k = i;
            }
            return root;
        }
        //合并顶点a和顶点b所在的树
        public void union(int[] id, int a, int b) {
            int rootA = find(id, a);
            int rootB = find(id, b);
            if(rootA == rootB)
                return;
            int rootNum = id[rootA] + id[rootB];
            if(id[rootA] < id[rootB]) {
                id[rootB] = rootA;
                id[rootA] = rootNum;
            } else{
                id[rootA] = rootB;
                id[rootB] = rootNum;
            }
            return;
        }
        
        public void init() {
            count = 0;
            for(int i = 0;i < 51;i++) {
                id[i] = -1;   //初始化所有顶点所在树的根节点编号为-1
                degree[i] = 0;
            }
            for(int i = 0;i < MAX;i++) {
                used[i] = false;
                path[i] = "";
            }
            return;
        }
        
        public boolean judge(ArrayList<edge>[] map) {
            int root = find(id, start);
            for(int i = 0;i < map.length;i++) {
                for(int j = 0;j < map[i].size();j++) {
                    if(root != find(id, map[i].get(j).b))
                        return false;
                }
            }
            for(int i = 0;i < degree.length;i++) {
                if(degree[i] % 2 != 0)
                    return false;
            }
            return true;
        }
        
        public void dfs(ArrayList<edge>[] map, int start) {
            for(int i = 0;i < map[start].size();i++) {
                if(!used[map[start].get(i).num]) {
                    used[map[start].get(i).num] = true;
                    path[count++] = map[start].get(i).getAB();
                    dfs(map, map[start].get(i).b);
                }
            }
        }
        
        public static void main(String[] args) {
            Main test = new Main();
            Scanner in = new Scanner(System.in);
            int t = in.nextInt();       //总共要输入的图的数目
            while(t > 0) {
                t--;
                @SuppressWarnings("unchecked")
                ArrayList<edge>[] map = new ArrayList[51];
                for(int i = 0;i < 51;i++)
                    map[i] = new ArrayList<edge>();
                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, num));
                    map[b].add(new edge(b, a, num++));
                    degree[a]++;
                    degree[b]++;
                    test.union(id, a, b);
                    start = a;
                }
                String temp = "";
                if(test.judge(map)) {
                    test.dfs(map, start);
                    for(int i = 0;i < k;i++) {
                        temp = temp + path[i] + "
    ";
                    }
                } else {
                    temp = "some beads may be lost";
                }
                result.add(temp);
            }
            for(int i = 0;i < result.size();i++) {
                System.out.println("Case #"+(i+1));
                System.out.println(result.get(i)+"
    ");
            }
        }
    }

    运行结果:

    2
    5
    1 2
    2 3
    3 4
    4 5
    5 6
    5
    2 1
    2 2
    3 4
    3 1
    2 4
    Case #1
    some beads may be lost
    
    Case #2
    2 1
    1 3
    3 4
    4 2
    2 2

     

     

     

     

    参考资料:

       1.欧拉回路

  • 相关阅读:
    Django的中间件
    Django的Models(三)
    多个SSH key对应多个Host: Github, Bitbucket
    最简单的私有库方法
    Swift compile slow 编译慢问题
    Hide Xcode8 strange log.
    cocoapods 终极方案
    "Mac OS X"想要进行更改。键入管理员的名称和密码以允许执行此操作("Mac OS X"想使用系统钥匙串)
    Xcode7下载地址
    Xcode8安装不成功, 需要升级系统. The operation couldn't be completed. cpio read error
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/6755995.html
Copyright © 2011-2022 走看看