您的位置:首页 > 其它

CSU 1806 Toll

2016-09-05 19:52 246 查看


Description

 In ICPCCamp, there are n cities and m unidirectional roads between cities. The i-th road goes from the ai-th city
to the bi-th city. For each pair of cities u and v, there is at most one road from u to v.
As traffic in ICPCCamp is becoming heavier, toll of the roads also varies. At time t, one should pay (ci⋅t+di)
dollars to travel along the i-th road.
Bobo living in the 1-st city would like to go to the n-th city. He wants to know the average money he must spend at least if he starts from city 1 at t∈[0,T]. Note that since Bobo's car is super-fast, traveling on the roads costs him no
time
.
Formally, if f(t) is the minimum money he should pay from city 1 to city n at time t, Bobo would like to find




Input

The first line contains 3 integers n,m,T (2≤n≤10,1≤m≤n(n-1),1≤T≤104).
The i-th of the following m lines contains 4 integers ai,bi,ci,di (1≤ai,bi≤n,ai≠bi,0≤ci,di≤103).
It is guaranteed that Bobo is able to drive from city 1 to city n.


Output

 A floating number denotes the answer. It will be considered correct if its absolute or relative error does not exceed 10-6.


Sample Input

3 3 2
1 2 1 0
2 3 1 0
1 3 1 1
3 3 2
1 2 1 0
2 3 1 0
1 3 0 5


Sample Output

1.75000000
2.00000000
有一个积分公式,看似很难的题。
稍微分析一下,其实可以发现,因为c和d是非负整数,显然,从1到n的花费只会随时间增加而增加。
并且,可以发现,对于同一时间,我们会优先选择通过路上∑ci较小的路,因为∑di是不会随时间变动的。
于是,可以以∑ci分段,对于同一段里,∑ci和∑di一定是相同的,
这一段的积分就是(r-l)*((r+l)/2)*∑ci+∑di),最后加起来除于t即可。
#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define loop(i,j,k) for (int i = j;i != -1; i = k[i])
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
#define ff first
#define ss second
#define mp(i,j) make_pair(i,j)
#define pb push_back
#define pii pair<int,int>
#define in(x) scanf("%d", &x);
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const double eps = 1e-8;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 15;
int n, m, t, x, y;
int c

, d

;
double dis
;
int u
, v
, vis
;

pii check(double t)
{
rep(i, 1, n) dis[i] = -1, u[i] = v[i] = vis[i] = 0;
dis[1] = 0;
while (true)
{
x = 0;
rep(i, 1, n)
{
if (dis[i] < 0 || vis[i]) continue;
if (!x || dis[i] < dis[x]) x = i;
}
if (!x) break; vis[x] = 1;
rep(i, 1, n)
{
if (c[x][i] == -1) continue;
if (dis[i]<0 || dis[i] - eps > dis[x] + t*c[x][i] + d[x][i])
{
dis[i] = dis[x] + t*c[x][i] + d[x][i];
u[i] = u[x] + c[x][i];
v[i] = v[x] + d[x][i];
}
else if (fabs(dis[x] + t*c[x][i] + d[x][i] - dis[i]) < eps)
{
if (u[i] > u[x] + c[x][i])
{
u[i] = u[x] + c[x][i];
v[i] = v[x] + d[x][i];
}
}
}
}
return mp(u
, v
);
}

int main()
{
while (scanf("%d%d%d", &n, &m, &t) != EOF)
{
memset(c, -1, sizeof(c));
while (m--)
{
scanf("%d%d", &x, &y);
scanf("%d%d", &c[x][y], &d[x][y]);
}
double l = 0, r = t, ans = 0;
pii bef = check(l);
while (l + eps < r)
{
double q = l, h = r;
pii now;
while (q + eps < h)
{
now = check((q + h) / 2);
if (now.ff == bef.ff) q = (q + h) / 2;
else h = (q + h) / 2;
}
ans += (h - l) * ((h + l) / 2 * bef.ff + bef.ss);
bef = check(l = h);
}
printf("%.8lf\n", ans / t);
}
return 0;
}
去翻了翻网上的题解,看到的全是simpson求积分,吓得我赶紧去学了一发,原来还有这么好用的东西。
#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define loop(i,j,k) for (int i = j;i != -1; i = k[i])
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
#define ff first
#define ss second
#define mp(i,j) make_pair(i,j)
#define pb push_back
#define pii pair<int,int>
#define in(x) scanf("%d", &x);
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const double eps = 1e-8;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 15;
int n, m, t, x, y;
int c

, d

;
double dis
;
int vis
;

double get(double t)
{
rep(i, 1, n) dis[i] = -1, vis[i] = 0;
dis[1] = 0;
while (true)
{
x = 0;
rep(i, 1, n)
{
if (dis[i] < 0 || vis[i]) continue;
if (!x || dis[i] < dis[x]) x = i;
}
if (!x) break; vis[x] = 1;
rep(i, 1, n)
{
if (c[x][i] == -1) continue;
if (dis[i] > eps && dis[i] + eps < dis[x] + t*c[x][i] + d[x][i]) continue;
dis[i] = dis[x] + t * c[x][i] + d[x][i];
}
}
return dis
;
}

double simpson(double l, double r)
{
return (r - l) / 6 * (get(l) + 4 * get((l + r) / 2) + get(r));
}

double solve(double l, double r)
{
double mid = (l + r) / 2, now = simpson(l, r);
if (fabs(simpson(l, mid) + simpson(mid, r) - now) < eps) return now;
return solve(l, mid) + solve(mid, r);
}

int main()
{
while (scanf("%d%d%d", &n, &m, &t) != EOF)
{
memset(c, -1, sizeof(c));
while (m--)
{
scanf("%d%d", &x, &y);
scanf("%d%d", &c[x][y], &d[x][y]);
}
printf("%.8lf\n", solve(0, t) / t);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: