算法笔记_148:有向图欧拉回路求解(Java)
Posted 舞动的心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法笔记_148:有向图欧拉回路求解(Java)相关的知识,希望对你有一定的参考价值。
目录
1 问题描述
Description
A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms:
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
dog.gopher
gopher.rat
rat.tiger
aloha.aloha
arachnid.dog
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
Input
The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.
Output
For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.
Sample Input
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
Sample Output
aloha.arachnid.dog.gopher.rat.tiger
***
Source
2 解决方案
具体代码如下:
package com.liuzhen.practice; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main { public static int MAX = 30; //英文字母共26个 @SuppressWarnings("unchecked") public static ArrayList<edge>[] map = new ArrayList[MAX]; public static String[] path; public static int count; //统计DFS遍历访问的边数目,即检测图的连通性 public static int start; public static int[] inDegree = new int[MAX]; public static int[] outDegree = new int[MAX]; public static ArrayList<String> result = new ArrayList<String>(); class MyComparator implements Comparator<edge> { public int compare(edge arg0, edge arg1) { String A = arg0.word; String B = arg1.word; int judge = A.compareTo(B); if(judge > 0) return 1; else if(judge < 0) return -1; return 0; } } static class edge { public int a; //单词的第一个字母序号 public int b; //单词最后一个字母序号 public String word; //具体单词 public boolean used; //判断单词是否被访问 public edge(int a, int b, String word) { this.a = a; this.b = b; this.word = word; used = false; } } public void init(int k) { start = MAX; for(int i = 0;i < MAX;i++) { map[i] = new ArrayList<edge>(); inDegree[i] = 0; outDegree[i] = 0; } path = new String[k]; for(int i = 0;i < k;i++) path[i] = ""; count = 0; } public boolean judgeDegree() { int in = 0, out = 0; for(int i = 1;i < map.length;i++) { //对map[i]中单词进行字典序排序 if(map[i].size() > 1) Collections.sort(map[i], new MyComparator()); } for(int i = 0;i < inDegree.length;i++) { if(inDegree[i] == outDegree[i]) continue; else if(inDegree[i] - outDegree[i] == 1) in++; else if(outDegree[i] - inDegree[i] == 1) { out++; start = i; //此时,可能存在欧拉路径,必须从入度小于出度的点开始遍历 } else return false; } if(in == out && (in == 0 || in == 1)) return true; return false; } public void dfs(int begin) { for(int i = 0;i < map[begin].size();i++) { edge temp = map[begin].get(i); if(temp.used == false) { temp.used = true; path[count++] = temp.word; dfs(temp.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--; int k = in.nextInt(); test.init(k); for(int i = 0;i < k;i++) { String A = in.next(); int a = A.charAt(0) - ‘a‘; int b = A.charAt(A.length() - 1) - ‘a‘; start = Math.min(start, Math.min(a, b)); map[a].add(new edge(a, b, A)); outDegree[a]++; inDegree[b]++; } StringBuilder temp = new StringBuilder(""); if(test.judgeDegree()) { //满足欧拉回路或者欧拉路径对顶点度的要求 test.dfs(start); if(count == k) { //图连通 for(int i = 0;i < k;i++) { temp.append(path[i]); if(i != k - 1) temp.append("."); } } else { temp.append("***"); } } else { temp.append("***"); } result.add(temp.toString()); } for(int i = 0;i < result.size();i++) System.out.println(result.get(i)); } }
运行结果:
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm aloha.arachnid.dog.gopher.rat.tiger ***
参考资料:
1. 欧拉回路
以上是关于算法笔记_148:有向图欧拉回路求解(Java)的主要内容,如果未能解决你的问题,请参考以下文章