##换教室
floyd三看:
dis[u][v]=dis[v][u]=min(dis[u][v],w)
mem了dis后,rep(i,1,点的个数)dis[i][i]=0
/*
debug:
注意读题啊……是双向通行的
reference:
ccf提高篇P279
Date:
2019.10.07
sol:
*/
const int N=2e3+10;
int n,m,v,e;
int c[N],d[N];
double k[N],f[N][N][2];
int dis[310][310];
int main(){
#ifdef WIN32
freopen("huanjiaoshi.txt","r",stdin);
#endif
rd(n),rd(m),rd(v),rd(e);
rep(i,1,n)rd(c[i]);rep(i,1,n)rd(d[i]);rep(i,1,n)scanf("%lf",&k[i]);
mem(dis,0x3f);
rep(i,1,v)dis[i][i]=0;
rep(i,1,e){
int u,v,w;rd(u),rd(v),rd(w);
dis[u][v]=dis[v][u]=min(dis[u][v],w);///////////////////////无向边!!!
}
rep(kk,1,v)
rep(i,1,v)
rep(j,1,v)
dis[i][j]=min(dis[i][j],dis[i][kk]+dis[kk][j]);
rep(i,1,n)
rep(j,0,m)
f[i][j][0]=f[i][j][1]=1.0*1e9;
f[1][0][0]=f[1][1][1]=0;
rep(i,2,n){
rep(j,0,min(i,m)){
//第i节课不申请
f[i][j][0]=min(f[i][j][0],
f[i-1][j][1]+k[i-1]*dis[d[i-1]][c[i]]+(1.0-k[i-1])*dis[c[i-1]][c[i]]);
f[i][j][0]=min(f[i][j][0],
f[i-1][j][0]+dis[c[i-1]][c[i]]);
//第i节课要申请
if(j>0){//得保证有上一堂课
f[i][j][1]=min(f[i][j][1],
f[i-1][j-1][0]+k[i]*dis[c[i-1]][d[i]]+(1.0-k[i])*dis[c[i-1]][c[i]]);
f[i][j][1]=min(f[i][j][1],
f[i-1][j-1][1]+
k[i-1]*k[i]*dis[d[i-1]][d[i]]+
k[i-1]*(1.0-k[i])*dis[d[i-1]][c[i]]+
(1.0-k[i-1])*k[i]*dis[c[i-1]][d[i]]+
(1.0-k[i-1])*(1.0-k[i])*dis[c[i-1]][c[i]]);
}
}
}
double ans=1e9*1.0;
rep(i,0,m)
ans=min(ans,min(f[n][i][0],f[n][i][1]));
printf("%.2lf",ans);
return 0;
}
原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634646.html
时间: 2024-10-29 15:19:57