88 pts 求调,悬关
查看原帖
88 pts 求调,悬关
580107
xixisuper楼主2024/7/5 11:55

rt,真调不动了。

#include <iostream>
#define ll int
#define dd double
using namespace std;
const ll N=2005;
const ll V=305;
const ll INF=998244353;
ll n,m,v,e,head[N],tot,x,y,z;
ll yuan[N],chg[N],ju[V][V];
dd lv[N],f[N][N],g[N][N];
int main(){
	scanf("%d%d%d%d",&n,&m,&v,&e);
	for(ll i=1;i<=n;i++) scanf("%d",&yuan[i]);
	for(ll i=1;i<=n;i++) scanf("%d",&chg[i]);
	for(ll i=1;i<=n;i++) scanf("%lf",&lv[i]);
	for(ll i=1;i<=v;i++)
		for(ll j=1;j<=v;j++){
			if(i!=j) ju[i][j]=INF;
			else ju[i][j]=0;
		}
	for(ll i=1;i<=e;i++){
		scanf("%d%d%d",&x,&y,&z);
		if(z>ju[x][y]||z>ju[x][y]) continue;
		ju[x][y]=ju[y][x]=z;
	}
	for(ll k=1;k<=v;k++)
		for(ll i=1;i<=v;i++)
			for(ll j=1;j<=v;j++)
				ju[i][j]=min(ju[i][j],ju[i][k]+ju[k][j]);
	//f[i][j] 表示上完了第 i 节课,还能换 j 次课,现在在原教室,期望还要走多远
	//g[i][j] 表示上完了第 i 节课,还能换 j 次课,现在在另一个教室,期望还要走多远
	for(ll i=n-1;i>=1;i--){
		for(ll j=0;j<=m;j++){
			f[i][j]=(dd)ju[yuan[i]][yuan[i+1]]+f[i+1][j];
			g[i][j]=(dd)ju[chg[i]][yuan[i+1]]+f[i+1][j];
			if(j<m){
				f[i][j]=min(f[i][j],lv[i+1]*((dd)ju[yuan[i]][chg[i+1]]+g[i+1][j+1])+(1.0-lv[i+1])*((dd)ju[yuan[i]][yuan[i+1]]+f[i+1][j+1]));
				g[i][j]=min(g[i][j],lv[i+1]*((dd)ju[chg[i]][chg[i+1]]+g[i+1][j+1])+(1.0-lv[i+1])*((dd)ju[chg[i]][yuan[i+1]]+f[i+1][j+1]));
			}
		}
	}
	dd ans=f[1][0];
	if(m) ans=min(ans,lv[1]*g[1][1]+(1.0-lv[1])*f[1][1]);
	printf("%.2lf",ans);
	return 0;
}
2024/7/5 11:55
加载中...