题意

思路
动态规划。我们可以把去的路和来的路分开做,设f[i][j]f[i][j]表示第一个点走到ii,第二个点(回去的那个点)走到的最优值,可以得出动态转移方程:
f[i][k]=min(f[i][k],f[i][j]+dis[j][k]f[i][k]=min(f[i][k],f[i][j]+dis[j][k]
f[k][j]=min(f[k][j],f[i][j]+dis[i][k])f[k][j]=min(f[k][j],f[i][j]+dis[i][k])
至于特殊的两个点我们可以在枚举的时候进行特判。
代码
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int x[1001],y[1001],n,c1,c2;
double f[1001][1001],d[1001][1001];
int main()
{
scanf("%d%d%d",&n,&c1,&c2);
++c1;++c2;
for(int i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
d[j][i]=d[i][j]=(double)sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));//两个点的直线距离
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
f[i][j]=2147483647/3;
f[1][1]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int k=max(i,j)+1;
if(k==n+1)//特判n
{
if (i!=n) f[n][n]=min(f[n][n],f[i][j]+d[i][n]);
if (j!=n) f[n][n]=min(f[n][n],f[i][j]+d[j][n]);
continue;
}
if(k!=c1) f[i][k]=min(f[i][k],f[i][j]+d[j][k]);//特判特殊点
if(k!=c2) f[k][j]=min(f[k][j],f[i][j]+d[i][k]);
}
printf("%.2lf",f[n][n]);
}

本文介绍了一种使用动态规划来解决特定旅行问题的方法。通过定义状态f[i][j]为从起点到i,同时另一路径到j的最优值,利用动态转移方程实现了对最短路径的有效计算。
1541

被折叠的 条评论
为什么被折叠?



