最短路径
解题思路
考虑状压
D
P
DP
DP。
设
f
i
,
j
f_{i,j}
fi,j 为已经走过的状态为
i
i
i ,当前节点为
j
j
j 的最小值。
每次枚举一条路径的起点和终点进行转移,转移方程为:
f
i
,
j
=
min
(
f
i
−
(
1
<
<
j
−
1
)
,
k
+
a
k
,
j
)
f_{i,j}=\min(f_{i-(1<<j-1),k}+a_{k,j})
fi,j=min(fi−(1<<j−1),k+ak,j)
code
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n;
int a[30][30];
int f[1<<21][30];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(f,0x3f3f3f3f,sizeof(f));
f[1][1]=0;
for(int i=1;i<(1<<n);i++)
for(int j=1;j<=n;j++)
if(i&(1<<j-1))
for(int k=1;k<=n;k++)
if(i&(1<<k-1))
f[i][j]=min(f[i][j],f[i-(1<<j-1)][k]+a[k][j]);
printf("%d",f[(1<<n)-1][n]);
}