Repairing a Road

原题描述:

You live in a small town with R bidirectional roads connecting C crossings and you want to go from crossing 1 to crossing C as soon as possible. You can visit other crossings before arriving at crossing C, but it’s not mandatory.

 

You have exactly one chance to ask your friend to repair exactly one existing road, from the time you leave crossing 1. If he repairs the i-th road for t units of time, the crossing time after that would be viai-t. It's not difficult to see that it takes vi units of time to cross that road if your friend doesn’t repair it.

 

You cannot start to cross the road when your friend is repairing it.

 

Input

There will be at most 25 test cases. Each test case begins with two integers C and R (2<=C<=100, 1<=R<=500). Each of the next R lines contains two integers xi, yi (1<=xi, yi<=C) and two positive floating-point numbers vi and ai (1<=vi<=20,1<=ai<=5), indicating that there is a bidirectional road connecting crossing xi and yi, with parameters vi and ai (see above). Each pair of crossings can be connected by at most one road. The input is terminated by a test case with C=R=0, you should not process it.

 

Output

For each test case, print the smallest time it takes to reach crossing C from crossing 1, rounded to 3 digits after decimal point. It’s always possible to reach crossing C from crossing 1.

题目大意:

  

有一个C个点R条无向边的图,每条边有花费vi和一个ai。现在有一个人,可以花费t的时间该修一条道路,修的时候此路不通。如果总共修了t时间,那么这条路的花费就会变成 vi * ai ^ (-t)。要从1走到C,求最小花费。

思路:

    根据题意时间越长越好,其次,如果我们要修(x, y)这条边,我们要从x走到y,我们可能要先在x等一段时间,然后再从x走到y。我们等了一段时间再过去,路的花费也就减少了,可能要比我们直接走过去花的时间要更少。。比如经过一条边(x, y)的最短路径就是dis(1,x) + (t - dis(1, x)) + vi * ai ^ (-t) + dis(y, C),第二个是可能站在x等待的时间,从最优的角度考虑t肯定是不会小于dis(1, x)。

其中dis(a, b)代表从a走到b所需要的最小花费。我们可以从1开始做单源最短路径,再从C开始做单源最短路径。C的数据不大,果断floyd。

设f(t) = dis(1, x) + (t - dis(1, x)) + vi * ai ^ (-t) + dis(y, C),看到这个函数我们只能先求导:f'(t) = 1 - ln(ai) *vi * ai ^ (-t),求这个函数的零点,这是一个单调的函数,果断二分求解0点。下界很简单,就是dis(1,x),那么上界呢?上界我们可以定为当前答案ans(初始化为dis(1, C)),因为如果修的时间比这个还多就没有意义了。问题是,这个是区间求零点,很可能没有零点,怎么办?如果零点在dis(1, x)的左边,那么t取dis(1, x)就好。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double MAX=1e-6;
double rood[101][101];
int x[501], y[501];
double v[501], a[501];
double find( int i, int x, int y, double l, double r)
{
     double ll=l,rr=r,mm;
     while (rr-ll>MAX)
     {
         double avg=(ll+rr)/2;
         mm=1- log (a[i])*v[i]* pow (a[i],-avg);
         if (mm>0) rr=avg;
         else ll=avg;
     }
     mm=1- log (a[i])*v[i]* pow (a[i],-ll);
     if ( fabs (mm)<MAX)
         return ll;
     if (mm>0)
         return l;
     return ll;
}
void money( int n, int m) 
{
     int i;
     double t,ans=rood[1][n];
     for (i=0;i<m;i++) 
     {
         t = find(i,x[i],y[i],rood[1][x[i]],ans);
         if (ans>t+v[i]* pow (a[i],-t)+rood[y[i]][n])
             ans=t+v[i]* pow (a[i],-t)+rood[y[i]][n];
         t = find(i,y[i],x[i],rood[1][y[i]],ans);
         if (ans>t+v[i]* pow (a[i],-t)+rood[x[i]][n])
             ans=t+v[i]* pow (a[i],-t)+rood[x[i]][n];
     }
     printf ( "%.3f\n" ,ans);
}
int main()
{
     int n,m;
     while (cin>>n>>m && n && m)
     {
         int i,j,k;
         for (i=1;i<=n;i++)
         {
             for (j=1;j<=n;j++)
                 rood[i][j]=100000;
             rood[i][i]=0;
         }
         for (i=0;i<m;i++)
         {
             scanf ( "%d%d%lf%lf" ,&x[i],&y[i],&v[i],&a[i]);
             if (rood[x[i]][y[i]]>v[i])
                 rood[x[i]][y[i]]=v[i];
             if (rood[y[i]][x[i]]>v[i])
                 rood[y[i]][x[i]]=v[i];
         }
         for (k=1;k<=n;k++)
             for (i=1;i<=n;i++)
                 for (j=1;j<=n;j++)
                     if (rood[i][j]>rood[i][k]+rood[k][j])
                         rood[i][j]=rood[i][k]+rood[k][j];
         money(n,m);
     }
     return 0;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
This error message typically appears when WordPress is unable to connect to the database that stores all of your site's content, settings, and user data. There are several potential causes for this error, including: 1. Incorrect database login credentials: If the database login credentials in your wp-config.php file are incorrect, WordPress won't be able to connect to the database. 2. Corrupted database: If your WordPress database becomes corrupted, it may not be able to establish a connection. 3. Database server issues: If the database server is down or experiencing issues, WordPress won't be able to connect. 4. Exceeded database limits: If your website has exceeded the database limits set by your hosting provider, you may not be able to connect. 5. Incorrect database host: If the database host in your wp-config.php file is incorrect, WordPress won't be able to connect to the database. To resolve this issue, you can try the following steps: 1. Check your wp-config.php file to ensure that your database login credentials are correct. 2. Try repairing your WordPress database using a tool like phpMyAdmin. 3. Contact your hosting provider to see if there are any issues with the database server. 4. Check if your website has exceeded the database limits set by your hosting provider and upgrade if necessary. 5. Double-check that the database host in your wp-config.php file is correct. If none of these steps work, you may need to contact your hosting provider or a WordPress developer for further assistance.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值