CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连。因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同。小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度。
现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线。请你告诉他这个值。
第一行包含一个整数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,其余保证为正整数。
写入一个实数S,为小区1到达n的最大答案,S精确到小数点后3位。
3
0 8 7
9 0 10
5 7 0
0 7 6
6 0 6
6 2 0
2.125
【数据说明】
30%的数据,n<=20
100%的数据,n<=100,p,t<=10000
直接跑最短路记录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的最长路即可(注意判断正权环)
1 // This file is made by YJinpeng,created by XuYike‘s black technology automatically. 2 // Copyright (C) 2016 ChangJun High School, Inc. 3 // I don‘t know what this program is. 4 5 #include <iostream> 6 #include <vector> 7 #include <algorithm> 8 #include <cstring> 9 #include <cstdio> 10 #include <cstdlib> 11 #include <cmath> 12 #include <queue> 13 #define MOD 1000000007 14 #define INF 1e9 15 #define EPS 1e-5 16 using namespace std; 17 typedef long double LB; 18 const int MAXN=110; 19 const int MAXM=100010; 20 inline int gi() { 21 register int w=0,q=0;register char ch=getchar(); 22 while((ch<‘0‘||ch>‘9‘)&&ch!=‘-‘)ch=getchar(); 23 if(ch==‘-‘)q=1,ch=getchar(); 24 while(ch>=‘0‘&&ch<=‘9‘)w=w*10+ch-‘0‘,ch=getchar(); 25 return q?-w:w; 26 } 27 int p[MAXN][MAXN],t[MAXN][MAXN],num[MAXN]; 28 queue<int>q;LB d[MAXN];int n;bool u[MAXN]; 29 bool check(LB k){ 30 for(int i=1;i<=n;i++)d[i]=-1e16; 31 q.push(1);d[1]=0;memset(u,0,sizeof(u));memset(num,0,sizeof(num)); 32 while(!q.empty()){ 33 int x=q.front();q.pop();u[x]=0; 34 for(int o=1;o<=n;o++) 35 if(o!=x) 36 if(d[x]+p[x][o]-t[x][o]*k>d[o]){ 37 d[o]=d[x]+p[x][o]-t[x][o]*k; 38 if(!u[o])u[o]=1,q.push(o),num[o]++; 39 if(num[o]>n)return true; 40 } 41 } 42 return d[n]>=0; 43 } 44 int main() 45 { 46 freopen("1183.in","r",stdin); 47 freopen("1183.out","w",stdout); 48 n=gi(); 49 for(int i=1;i<=n;i++) 50 for(int j=1;j<=n;j++) 51 p[i][j]=gi(); 52 for(int i=1;i<=n;i++) 53 for(int j=1;j<=n;j++) 54 t[i][j]=gi(); 55 LB l=0,r=INF; 56 while(r-l>EPS){ 57 LB m=(l+r)/2.0; 58 if(check(m))l=m; 59 else r=m; 60 }printf("%.3lf",double(r)); 61 return 0; 62 }
原文:http://www.cnblogs.com/YJinpeng/p/5958589.html