如果我是新手我肯定用最短路做,结果肯定被坑,因为送外卖的人可以重复的走某个道路多次,反正只要能够使最后的路程最短并且会回到送外外卖的起点就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; }