问题描述
给出一个有向图,输出这个图的一个哈密尔顿回路。
输入格式
输入的第一行包含两个整数n, m,分别表示图的点数和边数。
接下来m行,每行包含两个整数,表示一条边的起点和终点。
输出格式
输出一行,包含一个n个整数,表示一条哈密尔顿回路。如果没有回路输出“No Answer””。
数据规模和约定
1<=n<=20,图中没有重边。
哈密尔顿回路
若图G中一个回路通过且仅通过每一个顶点一次,称这个环为哈密顿回路。
bfs,耗时太久没有通过全部样例,得分 84
package ADV;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
public class ADV319 {
static String[] s;
static int[] ans = new int[20];
static int n,m;
static int[] vis;
static HashMap<Integer,ArrayList<Integer>> map = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
s = in.readLine().split(" ");
n = Integer.valueOf(s[0]);m = Integer.valueOf(s[1]);
vis = new int[n+1];
for (int i = 0; i < m; i++) {
int from,to;
s = in.readLine().split(" ");
from = Integer.valueOf(s[0]);to = Integer.valueOf(s[1]);
if(map.containsKey(from)) {
map.get(from).add(to);
}else {
ArrayList<Integer> L = new ArrayList<Integer>();
L.add(to);
map.put(from, L);
}
}
if(bfs(1,0,ans)) {//因为是回路,所以从哪个点找都可以
for (int i = 0; i < n; i++) {
if(i==0) {
System.out.print(ans[i]);
}else {
System.out.print(" "+ans[i]);
}
}
}else {
System.out.print("No Answer");
}
}
/**
*
* @param start 当前从哪个点开始(未进入ans)
* @param lv 下一个点应存放的位置
* @param ans 保存路径
* @return
*/
static boolean bfs(int start,int lv,int[] ans) {
ArrayList<Integer> edges = map.get(start);
ans[lv] = start;
lv++;
vis[start] = 1;
if(lv == n) {//找到了哈密尔顿路径,判断是否是回路
boolean isLoop = false;
for (Integer to : edges) {
if(to == 1) {
isLoop = true;
break;
}
}
if(isLoop) {
return true;
}else {
return false;
}
}
if(edges == null) {//没找到哈密尔顿路径,又不能进入下一点
return false;
}
boolean flag = false;
for (Integer to : edges) {//进入下一点
if(vis[to]==0) {
flag = bfs(to,lv,ans);
vis[to]=0;
if(flag) {//找到了哈密尔顿回路,立刻返回
return flag;
}
}
}
return flag;
}
}