zoukankan      html  css  js  c++  java
  • Codevs 1183 泥泞的道路

    1183 泥泞的道路

     
     
    题目描述 Description

    CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连。因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同。小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的时间以及这条路的长度。

    现在小A在小区1,他希望能够很顺利地到达目的地小区n,请帮助小明找出一条从小区1出发到达小区n的所有路线中(总路程/总时间)最大的路线。请你告诉他这个值。

    输入描述 Input Description

    第一行包含一个整数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 Description

    写入一个实数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

    数据范围及提示 Data Size & Hint

    【数据说明】

    30%的数据,n<=20

    100%的数据,n<=100,p,t<=10000

    /*
      由题意可得 (P1+...+Pn)/(T1+...Tn)=ans
      ------->   ans*(T1+...Tn)=(P1+...+Pn)
      ------->   P1-ans*T1+...+Pn-ans*Tn=0
      所以我们可以二分一个ans,根据f=p-ans*t 计算出一个f[][],
      然后用SPFA求最长路检验ans,如果一个形成正环,则说明一定存在更优的解,
      且当dis[n]>0时,也存在更优的解,否则,该ans不正确 
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    int n;
    queue<int>q;
    #define maxn 110
    double s[maxn][maxn],t[maxn][maxn],dis[maxn],l,r,a[maxn][maxn],step[maxn];
    bool vis[maxn];
    bool spfa(){
        memset(dis,-0x3f3f3f3f,sizeof(dis));
        memset(step,0,sizeof(step));
        memset(vis,0,sizeof(vis));
        while(!q.empty())q.pop();
        q.push(1);vis[1]=1;dis[1]=0;
        while(!q.empty()){
            int point=q.front();q.pop();vis[point]=0;
            for(int i=1;i<=n;i++){
                if(i!=point&&dis[i]<dis[point]+a[point][i]){
                    dis[i]=dis[point]+a[point][i];
                    if(!vis[i]){
                        vis[i]=1;
                        q.push(i);
                        step[i]++;
                        if(step[i]>n)return 1;
                    }
                }
            }
        }
        if(dis[n]>0)return 1;
        return 0;
    }
    bool check(double x){
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
            a[i][j]=s[i][j]-x*t[i][j];
        if(spfa())return 1;
        else return 0;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lf",&s[i][j]);
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lf",&t[i][j]);
        l=0;r=100000;
        while(r-l>0.0001){
            double mid=(l+r)/2.0;
            if(check(mid))l=mid;
            else r=mid;
        }
        printf("%.3lf",l);
    }
  • 相关阅读:
    jupyterlab数据处理
    系统监测模块
    登录验证码的实现
    编码格式检测chardet模块
    图像处理pillow模块
    内存数据的读取
    力扣(LeetCode)728. 自除数
    力扣(LeetCode)709. 转换成小写字母
    Java 层序创建和遍历二叉树
    力扣(LeetCode) 849. 到最近的人的最大距离
  • 原文地址:https://www.cnblogs.com/thmyl/p/7040905.html
Copyright © 2011-2022 走看看