算法笔记_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] + "\n";
                }
            } 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)+"\n");
        }
    }
}

 

运行结果:

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.欧拉回路

 

package hamierton; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Random; public class EularCircuit { public EularCircuit() { } public static void main(String[] args) { // System.out.println("please input n:"); // BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = 4; try { // n = Integer.parseInt(br.readLine()); } catch (Exception ex) { return; } try { Graph g = new Graph(n); g.printg(); g.circuit(); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); return; } } } class Node { private static int count = 0; private String name; private ArrayList adjacencyList; private boolean visited =false; public Node() { name = "node " + count; adjacencyList = new ArrayList(); } public Node(String name) { this.name = name; adjacencyList = new ArrayList(); } public boolean isAllVisited() { for (int i = 0; i < adjacencyList.size(); i++) { SNode sn = (SNode) adjacencyList.get(i); if (sn.visited == false) { return false; } } return true; } public boolean isvisited(){ return visited; } public void setvisited(){ visited = true; } public int getAdjacencyCount() { return adjacencyList.size(); } public boolean contains(int i) { return this.adjacencyList.contains(new SNode(i)); } public void removeAdjacencyNode(int i) { this.adjacencyList.remove(new SNode(i)); } public void addAdjacencyNode(int i) { this.adjacencyList.add(new SNode(i)); } public SNode getAdjacencyNode(int i) { return (SNode) this.adjacencyList.get(i); } public SNode getAdjacencyNodeEX(int i_ref) { for (int i = 0; i < this.getAdjacencyCount(); i++) { if (getAdjacencyNode(i).index == i_ref) { return getAdjacencyNode(i); } } return null; } public String toString() { return this.name; } } class SNode { public boolean visited = false; public int index = 0; public SNode(int index) { this.index = index; } public boolean equals(Object o) { if (((SNode) o).index == this.index) { return true; } return false; } public String toString() { return "adjacency " + index; } } class Graph { private ArrayList nodeList; private ArrayList path; private int count; public Graph(int n) throws Exception { this.count = n; nodeList = new ArrayList(count); ginit(); } public void circuit() { path = new ArrayList(); int top = 0; int k = 0; path.add(new Integer(0)); while (true) { int i, j; i = top; ArrayList path1 = new ArrayList(); path1.add(new Integer(top)); while (true) { Node node = (Node) nodeList.get(i); for (j = 0; j = path.size()) { break; } top = ((Integer) path.get(k)).intValue(); } for (int z = 0; z < path.size(); z++) { System.out.print(path.get(z).toString() + " "); } } private void ginit() { int i; for (i = 0; i < 4; i++) { nodeList.add(new Node("node" + i)); } ((Node)nodeList.get(0)).addAdjacencyNode(3); ((Node)nodeList.get(1)).addAdjacencyNode(0); ((Node)nodeList.get(2)).addAdjacencyNode(1); ((Node)nodeList.get(3)).addAdjacencyNode(2); // ((Node)nodeList.get(0)).addAdjacencyNode(3); // ((Node)nodeList.get(1)).addAdjacencyNode(0); // ((Node)nodeList.get(2)).addAdjacencyNode(1); // ((Node)nodeList.get(3)).addAdjacencyNode(2); // for (i = 0; i < n; i++) { // nodeList.add(new Node("node" + i)); // } // ArrayList linked = new ArrayList(); // linked.add(new Integer(0)); // Random rand = new Random(); // // for (i = 1; i = (linked.size() - 1 > 6 ? 6 // : linked.size() - 1)) { // continue; // } else { // i--; // } // node.addAdjacencyNode(randint); // Node randnode = (Node) nodeList.get(randint); // randnode.addAdjacencyNode(top); // break; // } // } // } // // for (i = 0; i < this.count - 1; i++) { // Node node = (Node) nodeList.get(i); // if (node.getAdjacencyCount() % 2 != 0) { // int j = 0; // for (j = i + 1; j < this.count; j++) { // Node nn = (Node) nodeList.get(j); // if (nn.getAdjacencyCount() % 2 != 0) { // if (node.contains(j)) { // // if (nn.getAdjacencyCount() != 1 // && node.getAdjacencyCount() != 1) { // node.removeAdjacencyNode(j); // nn.removeAdjacencyNode(i); // break; // } else { // continue; // } // } else { // // node.addAdjacencyNode(j); // nn.addAdjacencyNode(i); // break; // } // } // } // // if (j == this.count) { // int k; // Node nk = null; // for (k = i + 1; k < this.count; k++) { // // nk = (Node) nodeList.get(k); // if (nk.getAdjacencyCount() % 2 != 0) { // break; // } // } // int kk = k; // for (k = 0; k < i; k++) { // Node n1 = (Node) nodeList.get(k); // if (!n1.contains(kk) && !n1.contains(i)) { // n1.addAdjacencyNode(kk); // nk.addAdjacencyNode(k); // n1.addAdjacencyNode(i); // node.addAdjacencyNode(k); // break; // } // } // boolean retry = false; // // if (k == i) { // int vv; // for (vv = 0; vv < this.count; vv++) { // Node vn = (Node) nodeList.get(vv); // if (!vn.contains(i) && i != vv) { // vn.addAdjacencyNode(i); // node.addAdjacencyNode(vv); // retry = true; // break; // } // } // if (vv == count) { // for (vv = 0; vv 1) { // vnn.removeAdjacencyNode(i); // node.removeAdjacencyNode(vv); // retry = true; // break; // } // } // } // } // if (retry) { // i = -1; // } // } // } // // } // return this.isEularG(); } public boolean isEularG() { boolean isEular = true; for (int i = 0; i < this.count; i++) { Node n = (Node) nodeList.get(i); if (n.getAdjacencyCount() % 2 != 0) { isEular = false; break; } } return isEular; } public void printg() { for (int i = 0; i < this.count; i++) { Node n = (Node) nodeList.get(i); System.out.print(n.toString() + " "); for (int j = 0; j < n.getAdjacencyCount(); j++) { System.out.print(n.getAdjacencyNode(j).toString() + " "); } System.out.println(); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值