如果我是新手我肯定用最短路做,结果肯定被坑,因为送外卖的人可以重复的走某个道路多次,反正只要能够使最后的路程最短并且会回到送外外卖的起点就ok。那么只能用状态压缩dp了,看了下数据范围很小,状压无压力。
设置状态:
dp[st][k] 状态为st是终点为k的最短距离。
状态方程:dp[st][k] = min(dp[st][k], dp[i][j] + dis[j][k])
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define oo 0x3f3f3f3f
int dp[(1<<11)+1][11];
int Map[11][11];
int n;
void Floyd()
{
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
for(int k=0;k<=n;k++)
Map[i][j]=min(Map[i][j],Map[i][k]+Map[k][j]);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
scanf("%d",&Map[i][j]);
Floyd();
memset(dp,0x3f,sizeof dp);
int all=(1<<(n+1))-1;
dp[1][0]=0;
for(int i=0;i<=all;i++)
{
for(int j=0;j<=n;j++)
{
if(!(i&(1<<j))) continue;
if(dp[i][j]>=oo) continue;
for(int k=0;k<=n;k++)
{
if(k==j) continue;
int st=i|(1<<k);
dp[st][k]=min(dp[st][k],dp[i][j]+Map[j][k]);
}
}
}
printf("%d\n",dp[all][0]);
}
return 0;
}