zoj1655 最短路变形

题意:HERO过的首都需要货物,需要从其他的城市吧货物送到首都,每条道路都会需要消耗一定比例的货物,问最多能送多少货物到首都。

思路:如果每个点的比例是1,到达首都的比例就是经过的路径的(1-消耗比)的乘积,反正是无向的,所以可以反过来推,首都的货物比是1,而到达每座

城市的货物就是所经过的路径(1-消耗比)的乘积,则由此可见,我们可以求首都到任意城市的最大比值;最后把每个点的最大比值乘以每个点的货物加起来

即是结果。

#include<stdio.h>
#include<string.h>
const int maxn = 150;
const double lep = 1e-8;
double map[maxn][maxn];
int vis[maxn];
double dis[maxn];
int w[maxn];
int n,m;

void init()
{
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    for(int i=0;i<=n;i++)
    {
        for(int j =0;j<=n;j++)
            map[i][j] = -1;
    }
}
double  DIJ() // 求每座城市送物资的最大比值;
{
    int i,j;
    int u = n;
    dis[u] = 1;
    vis[u] = 1;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<n;j++)
        {
            if(!vis[j] && dis[j] < dis[u] * map[u][j])
            {
                dis[j] = dis[u] * map[u][j];
            }
        }
        double max  = 0;
        for(j=1;j<n;j++)
        {
            if(!vis[j] && dis[j] - max > lep)
            {
                max = dis[j];
                u = j;
            }
        }
        vis[u] =1;
    }
    double ans = 0;
    for(i= 1; i<n;i++)
        ans += w[i] * dis[i];
    return ans;
}
int main()
{
    int i;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(i=1;i<n;i++)
            scanf("%d",&w[i]);
        w[n]= 0;
        for(i=0;i<m;i++)
        {
            int a,b;
            double c;
            scanf("%d%d%lf",&a,&b,&c);
            if(map[a][b] < (1 - c) )
            {
                map[a][b] = map[b][a] = 1-c;
        //        printf("%lf
",map[a][b]);
            }
        }
        printf("%.2lf
",DIJ());
    }
    return 0;
}

/*
5 6
10
10
10
10
1 3 0
1 4 0
2 3 0
2 4 0
3 5 0
4 5 0

*/
原文地址:https://www.cnblogs.com/BruceNoOne/p/3900509.html