Zoj 1655 Transport Goods 最短路的应用

这道题目真是充分显示了窝的智商低下,首先题目在有中文翻译的情况下看了半天没看懂,= =

然后已知这题的分类是最短路了还是不会做,= =

一开始想着在dij扩展的的时候就把最大运送值算好,不过后来发现正向运输和反向运输的值显然是不相等的o(╯□╰)o

后来直接把每个城市作为起点dij了,反正n就一百,n^3就n^3了,后来发现可以从多条路一起送到终点

无奈看了题解,发现原来dij算的应该是终点到各个点的最小费率(最大比率),这样不仅正向反向算结果是一样的,而且不会漏。

话说题目本来就是要把每个城市里面的物品全部运送到终点的,只是对于每个城市选一条费率最小的边而已,这不是裸的dij么,这都不会,sad...

PS:这题有重边,WA哭TAT

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = INT_MAX / 4;
const int maxn = 105;
int vis[maxn],n,m,w[maxn];
double p[maxn][maxn],d[maxn];

void dijkstra() {
    memset(vis,0,sizeof(vis));
    for(int i = 1;i <= n;i++) {
        d[i] = -1;
    }
    d[n] = 1;
    for(int k = 1;k <= n;k++) {
        double maxv = -1; int x = n;
        for(int i = 1;i <= n;i++) if(!vis[i] && d[i] > maxv) {
            maxv = d[x = i];
        }
        vis[x] = true;
        for(int i = 1;i <= n;i++) if(!vis[i] && p[x][i] >= 0) {
            if(d[i] == -1) d[i] = d[x] * p[x][i];
            else d[i] = max(d[i],d[x] * p[x][i]);
        }
    }
}

int main() {
    while(scanf("%d%d",&n,&m) != EOF) {
        for(int i = 1;i < n;i++) {
            scanf("%d",&w[i]);
        }
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= n;j++) {
                p[i][j] = -5;
            }
        }
        for(int i = 1;i <= m;i++) {
            int a,b;
            double c; scanf("%d%d%lf",&a,&b,&c);
            p[a][b] = p[b][a] = max((1 - c),p[a][b]);
        }
        dijkstra();
        double ans = 0;
        for(int i = 1;i < n;i++) if(d[i] > 0) {
            ans += d[i] * w[i];
        }
        printf("%.2f\n",ans);
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/rolight/p/3847962.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值