[ACM湖南省赛] CSU 1806 动态最短路的积分

探讨了在一个有向图中,当边的权重随时间线性变化时,如何高效计算从0到T时间段内最短路径的平均值。通过将最短路径函数分解为线段并使用自适应辛普森积分法进行精确计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

给一个有向图,n<=10个点m条边,第i条边连接< ai,bi>,权值随时间t变化为ci*t+di。设t时刻最短路为f(t),求∫_0^T▒f(t)dt/T。

思路

边权是一次函数,最短路f(t)一定是一些线段组成的函数。理想情况是按照拐点划分,然后分段积分。这里如果区间中点等于左右端点的平均值那么就可以认为这里是一条直线,不必继续划分。而拐点数和点数同一规模,所以这样可以划分到很高的精度。因为被积函数是由一次函数连接的,所以不必用普通辛普森公式的二次拟合,直接用梯形算就好了。

AC代码 C

#include <stdio.h>
#include <string.h>
#include <math.h>

#define MAXN 12
#define INF 1e10

int n;
int G[MAXN][MAXN][2];

double forigin(double x)
{
    int i, j, k;
    static double dist[MAXN][MAXN];
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            dist[i][j] = G[i][j][0] < 0 ? INF : (double)G[i][j][0] * x + (double)G[i][j][1];
    for (k = 1; k <= n; k++)
        for (i = 1; i <= n; i++)
            for (j = 1; j <= n; j++)
                if (dist[i][j] > dist[i][k] + dist[k][j])
                    dist[i][j] = dist[i][k] + dist[k][j];
    return dist[1][n];
}//由forigin(x)得到某点被积函数的值

#define EPS 1e-8    //精度

double simpson(double l, double fl, double r, double fr)    //辛普森自适应积分
{
    double m = (l + r) * 0.5, fm = forigin(m);  //二分中点及其值
    return fabs(fl + fr - 2.0 * fm) < EPS ? fm * (r - l) : simpson(l, fl, m, fm) + simpson(m, fm, r, fr);
}//return那句的判断可以根据被积函数的特点改写

int main()
{
    int m, T, a, b, c, d;
    while (scanf("%d%d%d", &n, &m, &T) > 0)
    {
        memset(G, -1, sizeof G);
        while (m-- && scanf("%d%d%d%d", &a, &b, &c, &d) > 0)
        {
            G[a][b][0] = c;
            G[a][b][1] = d;
        }
        printf("%.8f\n", simpson(0, forigin(0), T, forigin(T)) / (double)T);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值