思路:状压dp
设一个f[M][N],N=21代表不同的教学楼,M=1<<N,M-1表示所有点已经到达,f[i][j]表示到达i状态且最后到达点是j时的路数
首先是初始化这个图
然后dp,对每个状态i,以出现在i中的目标j为目的地,遍历21栋教学楼找到可以到达j的点k,将dp[i-(1<<j)>>k][k]加到dp[i][j]里边
答案是881012367360
代码如下所示:
#include <iostream>
using namespace std;
typedef long long LL;
const int N=21,M=1<<N;
bool e[N][N];
LL f[M][N];
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
int main()
{
请在此输入您的代码
for(int i=1;i<=21;++i)
{
for(int j=i;j<=21;++j)
{
if(gcd(i,j)==1)
e[i-1][j-1]=e[j-1][i-1]=true;
}
}
f[1][0]=1;
for(int i=1;i<=M-1;++i)
{
for(int j=0;j<=20;++j)//计算以第j+1栋教学楼为目标 到达状态i的路数
{
if(i>>j&1)
{
for(int k=0;k<=20;++k)
{
if(i-(1<<j)>>k&1&&e[k][j])
{
f[i][j]+=f[i-(1<<j)][k];
}
}
}
}
}
LL ans=0;
for(int i=1;i<=20;++i)
{
ans+=f[M-1][i];
}
cout<<ans;
// cout<<881012367360;
return 0;
}