您的位置:首页 > 大数据 > 人工智能

UVA 11883 Repairing a Road(最短路径+暴力枚举)

2013-08-23 22:45 423 查看
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

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;

const int MAXN = 110;
const int MAXE = 1010;
const double EPS = 1e-6;

inline int sgn(double x) {
if(fabs(x) < EPS) return 0;
return x > 0 ? 1 : -1;
}

double fpai(double t, double v, double a) {
//t - v * pow(a, -t)
return 1 - log(a) * v * pow(a, - t);
}

inline void update_min(double &a, const double &b) {
if(a > b) a = b;
}

double mat[MAXN][MAXN];
int x[MAXE], y[MAXE];
double v[MAXE], a[MAXE];
int n, m;

void floyd() {
for(int k = 1; k <= n; ++k)
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j) update_min(mat[i][j], mat[i][k] + mat[k][j]);
}

double find_t(int i, int x, int y, double l, double r) {
double L = l, R = r;
while(R - L > EPS) {
double mid = (L + R) / 2;
//cout<<fpai(mid, v[i], a[i])<<endl;
if(fpai(mid, v[i], a[i]) > 0) R = mid;
else L = mid;
}
if(sgn(fpai(L, v[i], a[i])) != 0) return l;
return L;
}

double solve() {
double t, ans = mat[1]
;
for(int i = 0; i < m; ++i) {
t = find_t(i, x[i], y[i], mat[1][x[i]], ans);
update_min(ans, t + v[i] * pow(a[i], -t) + mat[y[i]]
);
t = find_t(i, y[i], x[i], mat[1][y[i]], ans);
update_min(ans, t + v[i] * pow(a[i], -t) + mat[x[i]]
);
}
return ans;
}

int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n == 0 && m == 0) break;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) mat[i][j] = 1e5;
mat[i][i] = 0;
}
for(int i = 0; i < m; ++i) {
int aa, bb; double cc;
scanf("%d%d%lf%lf", &aa, &bb, &cc, &a[i]);
x[i] = aa; y[i] = bb; v[i] = cc;
update_min(mat[aa][bb], cc);
update_min(mat[bb][aa], cc);
}
floyd();
printf("%.3f\n", solve());
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: