题目链接:点击打开链接
思路:
记忆化搜索。可以用一个14位的二进制进行状态压缩。第i位为1表示走过第i个点。由于起点和终点不用标记,所以只需要14位。
dp[i][j]记录已经走过了i状态的点,并且当前在j点的最短路。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stack>
#include<stdlib.h>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<ctype.h>
using namespace std;
#define LL long long
#define MAXN 10005
#define inf 1<<29
int n,G[20][20],dp[2<<15][17];
void dfs(int u,int len,int d)
{
if(d==(1<<(n-1))-1)
{
if(dp[d][n-1]==-1) dp[d][n-1]=len+G[u][n-1];
else dp[d][n-1]=min(dp[d][n-1],len+G[u][n-1]);
return;
}
for(int i=1;i<n-1;i++)
{
if((d>>i)&1) continue;
int td=d+(1<<i);
if(dp[td][i]!=-1 && dp[td][i]<=len+G[u][i]) continue;
dp[td][i]=len+G[u][i];
dfs(i,len+G[u][i],td);
}
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&G[i][j]);
memset(dp,-1,sizeof dp);
dfs(0,0,1);
printf("%d\n",dp[(1<<(n-1))-1][n-1]);
}
return 0;
}