蓝桥杯 哈密尔顿回路 Java

问题描述

给出一个有向图,输出这个图的一个哈密尔顿回路。

输入格式

输入的第一行包含两个整数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;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值