zoukankan      html  css  js  c++  java
  • ZOJ-1655 Transport Goods---dijkstra变形&&最长路

    题目链接:

    https://vjudge.net/problem/ZOJ-1655

    题目大意:

     有N-1个城市给首都(第N个城市)支援物资,有M条路,走每条路要耗费一定百分比的物资。问给定N-1个城市将要提供的物资,和每条路的消耗百分比。求能送到首都的最多的物资数量

    思路:

    由于每条路有费用率,比如1-2路的费用率是0.2,2-3的费用率是0.3,那么x质量的物品经1-3只剩下x*(1-0.2)*(1-0.3),一开始弄错了,以为消耗的是X*0.2*0.3,用最短路求,这显然是错误的,因为在路上消耗的不能算成费用率的乘积,比如之前的例子,在路上消耗的应该是x*0.2 + x*(1-0.8)*0.3,而直接计算剩余的,就可以用乘积的形式x*(1-0.2)*(1-0.3),所以直接将Map存为剩余率(1-费用率),而且数据中存在重边,所以要保存剩余率最大的那条边,然后用dijkstra求最长路,最长的话也是可dijkstra最短路思想一样,只是找出离源点的最短点变成离源点的最长点,更新dist时也是往大的更新,dist初始化时应该初始化成0。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<map>
     9 #include<set>
    10 #include<sstream>
    11 #define MEM(a, b) memset(a, b, sizeof(a));
    12 using namespace std;
    13 typedef long long ll;
    14 const int maxn = 100 + 10;
    15 const int INF = 0x3f3f3f3f;
    16 int T, n, m, cases, tot;
    17 int w[maxn];
    18 double Map[maxn][maxn];
    19 double d[maxn];//d[i]表示从源点到i的最大剩余率,由于是无向图,所以也是i到源点的最大剩余率
    20 bool v[maxn];
    21 void dijkstra(int u)
    22 {
    23     for(int i = 0; i <= n; i++)d[i] = 0;//初始化成最小的
    24     d[u] = 1;
    25     memset(v, 0, sizeof(v));
    26     for(int i = 0; i < n; i++)
    27     {
    28         int x;
    29         double m = 0;//这里是double!!!因为这个点一直WA
    30         for(int i = 1; i <= n; i++)if(!v[i] && d[i] - m > 1e-8)m = d[x = i];//这里改成找最大值
    31         v[x] = 1;
    32         for(int i = 1; i <= n; i++)
    33         {
    34             if(!v[i] && Map[x][i] >= 0)d[i] = max(d[i], d[x] * Map[x][i]);//松弛操作变成更新为最大值
    35         }
    36     }
    37 }
    38 int main()
    39 {
    40     while(cin >> n >> m)
    41     {
    42         for(int i = 1; i < n; i++)cin >> w[i];
    43         for(int i = 1; i <= n; i++)
    44             for(int j = 1; j <= n; j++)Map[i][j] = 0;
    45         int u, v;
    46         double c;
    47         while(m--)
    48         {
    49             cin >> u >> v >> c;
    50             Map[u][v] = Map[v][u] = max(1.0 - c, Map[u][v]);//有重边!!!
    51         }
    52         dijkstra(n);
    53         double ans = 0;
    54         for(int i = 1; i < n; i++)
    55         {
    56             ans = ans + 1.0 * w[i] * d[i];
    57         }
    58         printf("%.2f
    ", ans);
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    HQ-day8 函数
    HQ-day7 随机数案例:随机出验证码,对照输入,判断是否正确
    HQ-day6 C#类
    获取用户IP 查找所在城市
    MVC 日常所用
    SQLServer·面试题
    关于WCF开发 相应流程注意事项
    存储过程更新
    存储过程删除举例
    存储过程添加举例
  • 原文地址:https://www.cnblogs.com/fzl194/p/8735534.html
Copyright © 2011-2022 走看看