题解:P2269 [HNOI2002] 高质量的数据传输
Idea
看见 ,果断采用 Floyd。
在 Floyd 的过程中,我们维护两个数值:从 到 的最小丢包率,从 到 的延时(注意不一定是最短的)。
题目要求丢包率优先,我们直接模拟即可。注意到在丢包率小的情况下延时不一定最小,所以延时不可以取最小值。
接下来我们解决丢包率更新的问题。我们设现在枚举到了 (其中 为途经点),并且 和 , 和 之间均有连边,我们设 和 之间最小的丢包率为 ,则有经过 从 到 的最小丢包率 。
根据定义,我们不难发现:若使经过 从 到 的最小丢包率最小,必须使得 最大,其中 为使得经过 从 到 的丢包率最小所经过的一条边的丢包率。
不难发现如果保证 最小, 最小,则 和 一定最大。它们相乘的结果根据定义其实就是 ,用 减去它就是更新的答案。当然这个答案不一定最小。
Code
#include<bits/stdc++.h>
using namespace std;
double dis2[205][205],b[205][205];
long long dis1[205][205],a[205][205];
int n,s,t;
int main(){
cin>>n>>s>>t;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>dis1[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>dis2[i][j];
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dis1[i][k]==-1||dis1[j][k]==-1)continue;
double nans=1-(1-dis2[i][k])*(1-dis2[j][k]);
if(nans<dis2[i][j]){
dis2[i][j]=nans;
dis1[i][j]=dis1[i][k]+dis1[j][k];
}
else if(nans==dis2[i][j]&&dis1[i][j]>dis1[i][k]+dis1[j][k]){
dis1[i][j]=dis1[i][k]+dis1[j][k];
}
}
}
}
printf("%lld %.4lf",dis1[s][t],dis2[s][t]);
return 0;
}

浙公网安备 33010602011771号