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