Position:
List
Description
CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连。因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同。小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度。
现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线。请你告诉他这个值。
Input
第一行包含一个整数n,为小区数。
接下来n*n的矩阵P,其中第i行第j个数表示从小区i到小区j的道路长度为Pi,j。第i行第i个数的元素为0,其余保证为正整数。
接下来n*n的矩阵T,第i行第j个数表示从小区i到小区j需要的时间Ti,j。第i行第i个数的元素为0,其余保证为正整数。
Output
写入一个实数S,为小区1到达n的最大答案,S精确到小数点后3位。
Sample Input
3
0 8 7
9 0 10
5 7 0
0 7 6
6 0 6
6 2 0
Sample Output
2.125
HINT
【数据说明】
30%的数据,n<=20
100%的数据,n<=100,p,t<=10000
Solution
直接跑最短路记录v是错误的,后效性,就像两个溶液,c1+c2大,不一定混合就大(可能一个v很大)
对于这种分数题,很直接想到二分答案
∑p/∑t>ans(check满足),移过去,拆开,p[i]>ans×t[i],p[i]-ans×t[i]>0,以p[i]-ans×t[i]为关键字跑1~n的最长路即可(注意判断正权环)
Code
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is. #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#define MOD 1000000007
#define INF 1e9
#define EPS 1e-5
using namespace std;
typedef long double LB;
const int MAXN=;
const int MAXM=;
inline int gi() {
register int w=,q=;register char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-')q=,ch=getchar();
while(ch>=''&&ch<='')w=w*+ch-'',ch=getchar();
return q?-w:w;
}
int p[MAXN][MAXN],t[MAXN][MAXN],num[MAXN];
queue<int>q;LB d[MAXN];int n;bool u[MAXN];
bool check(LB k){
for(int i=;i<=n;i++)d[i]=-1e16;
q.push();d[]=;memset(u,,sizeof(u));memset(num,,sizeof(num));
while(!q.empty()){
int x=q.front();q.pop();u[x]=;
for(int o=;o<=n;o++)
if(o!=x)
if(d[x]+p[x][o]-t[x][o]*k>d[o]){
d[o]=d[x]+p[x][o]-t[x][o]*k;
if(!u[o])u[o]=,q.push(o),num[o]++;
if(num[o]>n)return true;
}
}
return d[n]>=;
}
int main()
{
freopen("1183.in","r",stdin);
freopen("1183.out","w",stdout);
n=gi();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
p[i][j]=gi();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
t[i][j]=gi();
LB l=,r=INF;
while(r-l>EPS){
LB m=(l+r)/2.0;
if(check(m))l=m;
else r=m;
}printf("%.3lf",double(r));
return ;
}