蓝桥杯-回路计数

题目描述
蓝桥学院由 21​​​ 栋教学楼组成,教学楼编号 1​​ 到 21​​。对于两栋教学楼 a​ 和 b​,
当 a​ 和b​ 互质时,a 和 b 之间有一条走廊直接相连,
两个方向皆可通行,否则没有直接连接的走廊。

小蓝现在在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),
请问他有多少种不同的访问方案?
 
两个访问方案不同是指存在某个 i,小蓝在两个访问方法中访问完教学楼 i 后访问了不同的教学楼。

本题考的是如何用代码求哈密顿路径。

21个教学楼可以想象成图的21个顶点,对于每一个顶点来说,要么有走过(1),要么没走过(0)。所有一共有2的21方个状态。

我们用f[i][j]表示当前为第i个状态,当前停在j顶点的方案数。

若当前为i状态,当前在j顶点,则从j顶点走到k顶点后就到达了状态i|1<<k.   ( i|1<<K表示在i状态下又走到了k顶点, i与i|1<<k相比的区别在于: i的二进制数中,第k位为0,而在i|1<<K的二进制数中,第k位为1),即i|1<<K比i多走了一个顶点k.

当然,从j顶点能走到k顶点的前提条件是j和k连通且在当前状态(i)下k未被走过。

根据以上分析,可得到状态转移方程为:

   f[i | (1 << k)][k] += f[i][j] ;

求哈密顿路径的代码如下:

f[1][0] = 1;   //f[1][0]表示在初始状态(即前面20位为0,最后一位为1)走到1号教学楼的方案数
	for (ll i = 1; i < n; ++i)
		for (int j = 0; j < 21; ++j)
			if (i >> j & 1)  //在第i个状态下能够走到j顶点
				for (int k = 0; k < 21; ++k)
					if (g[j][k] && !(i >> k & 1))   //j和k连通且在当前状态(i)下k未被走过
						f[i | (1 << k)][k] += f[i][j];   //状态转移方程,关键

经过上面的代码处理后,图中的所有哈密顿路径就都被求出来了。

n=1000,000,000,000,000,000,000

n-1= 111,111,111,111,111,111,111

由于n-1为一个21位的二进制数,且每一位都是1(即图中的21个顶点全部走过),所以

f[n-1][i]即表示最后一步走到顶点i的哈密顿路径数。

要求从i顶点出发的哈密顿回路数,只需在21个顶点都走过的前提下,从最后一个顶点走回i即可。

即 若j表示于i相连的顶点的编号,只需把f[n-1][j]累和起来即为答案。

本题是求从1出发的哈密顿回路数,而1与所有的顶点都连通,所以只需把j从1到21遍历,把f[n-1][j]累和起来即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值