codevs 2800 送外卖

状压。!!!!

这题神TM我调了不知道多久。。没带智商。

考虑好状态之间的关系。数组开够。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int dis[20][20],f[20][1<<17];
int n;
int main()
{
scanf("%d",&n);
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
scanf("%d",&dis[i][j]);
for (int k=0;k<=n;k++)
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
if ((dis[i][j]>dis[i][k]+dis[k][j]) && (i!=k) && (j!=k) && (i!=j))
dis[i][j]=dis[i][k]+dis[k][j];
memset(f,0x3f,sizeof(f));
int all=(1<<(n+1))-1;
for (int i=0;i<=n;i++)
f[i][1<<i]=dis[0][i];
for (int s=1;s<=all;s++)
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
{
if (((s&(1<<j))!=0) && ((s&(1<<i))!=0))
f[i][s]=min(f[i][s],f[j][s^(1<<i)]+dis[j][i]);
}
int res=0x3f3f3f3f;
for (int i=0;i<=n;i++)
res=min(res,f[i][all]+dis[i][0]);
printf("%d ",res);
return 0;
}

原文地址:https://www.cnblogs.com/ziliuziliu/p/5153780.html