DP分类讨论,状态定义
街道可以乱窜,起点终点确定,求遍历所有点的最短路径
感觉好难,只会10分
网络流暴力30分
哎~
做题要多思考,不要看题解,也不要看了题解就完了,还有很多做法
SOL:
参考自yyb
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+4;
int n[2],ty[2],pos[2];
double h,tx[2],a[2][N],f[N][2];
inline double dis(int i,int j){
static double d;
d=fabs(a[0][i]-a[1][j]);
return sqrt(d*d+h*h);
}
inline double toend(int i,int j){
static double d;
d=fabs(a[i][j]-tx[1]);
return i==ty[1]?d:sqrt(h*h+d*d);
}
inline double solve(){
double ret=1e18;
sort(a[0],a[0]+n[0]+1);
sort(a[1],a[1]+n[1]+1);
for(int i=n[0];i;--i){//0->(i,j+1) 1->(i+1,j)
if(i==n[0])for(int j=n[1];j;--j){
f[j][0]=(j==n[1]?toend(0,n[0]):min(f[j+1][1]+dis(i,j+1),dis(i,n[1])+a[1][n[1]]-a[1][j+1]+toend(1,j+1)));
f[j][1]=(j==n[1]?toend(1,n[1]):f[j+1][1]+a[1][j+1]-a[1][j]);
}//
else for(int j=n[1];j;--j)
if(j==n[1]){
f[j][1]=min(f[j][0]+dis(i+1,j),dis(n[0],n[1])+a[0][n[0]]-a[0][i+1]+toend(0,i+1));
f[j][0]+=a[0][i+1]-a[0][i];
}
else{
f[j][1]=min(f[j][0]+dis(i+1,j),f[j+1][1]+a[1][j+1]-a[1][j]);
f[j][0]=min(f[j+1][1]+dis(i,j+1),f[j][0]+a[0][i+1]-a[0][i]);
}
ret=min(ret,a[0][i]-a[0][1]+tx[0]-a[0][1]+dis(i,1)+f[1][1]);
ret=min(ret,fabs(a[0][i]-tx[0])+a[0][i]-a[0][1]+dis(1,1)+f[1][1]);
if(a[0][i]<=tx[0]){
ret=min(ret,tx[0]-a[0][1]+dis(1,1)+f[1][1]);
break;
}
}
return ret;
}
int main(){
scanf("%d%d%d%d%d%d%lf",&n[0],&n[1],&ty[0],&pos[0],&ty[1],&pos[1],&h);
int r=0;
if(ty[0]){r=1;swap(n[0],n[1]);ty[0]^=1;ty[1]^=1;}
for(int t=0;t^2;++t)
for(int i=1;i<=n[t^r];++i)
scanf("%lf",&a[t^r][i]);
tx[0]=a[ty[0]][pos[0]];
tx[1]=a[ty[1]][pos[1]];
double ans=solve();
for(int t=0;t^2;++t)
for(int i=1;i<=n[t];i++)
a[t][i]=20000-a[t][i];
tx[0]=20000-tx[0];
tx[1]=20000-tx[1];
ans=min(ans,solve());
printf("%.2lf",ans);
return (0-0);
}