観光牛poj3621

農夫のジョンは大都市のツアーに連れて行くことによって彼らのハードワークのために彼の牛に報酬を与えることに決めました!牛は、自由時間をどのように過ごすかを決定する必要があります。

幸いなことに、彼らは詳細に示した市内地図持つ  L  (2≤  L  ≤1000)主要なランドマーク(便宜1番...  L)と  P  (2≤  P  ≤5000)それらを結合一方向の牛のパスを。ファーマージョンは、牛を選択した開始ランドマークまで運転し、そこから他の一連のランドマークまでの牛の小道を歩き、ファーマージョンが牛をピックアップして農場に連れ戻す最初のランドマークまで戻ります。 。市内のスペースが貴重であるため、牛の道は非常に狭く、各牛の道に沿った移動は一定の方向にのみ許可されています。

牛は街で好きなだけ時間を過ごすかもしれませんが、退屈する傾向があります。新しいランドマークを訪れるのは楽しいですが、それらの間を歩くには時間がかかります。牛は、正確な楽しい値を知っている  F I  (1≤  F I  各ランドマーク1000≤)  私を

牛は牛の道も知っています。Cowpath  iが  ランドマーク接続  L 1はiが  に  L 2 I  (方向における  L 1 、I  - >  L 2 私は  )と時間が必要  T I  (1≤  T I  トラバースに≤1000)。

牛は可能な限り最高の休日を過ごすために、旅行の単位時間あたりの平均楽しみ値を最大化したいと考えています。もちろん、ランドマークは初めて訪れたときだけ楽しいものです。牛はランドマークを2回以上通過する可能性がありますが、その楽しみの価値を再認識しません。さらに、ファーマージョンは、牛が少なくとも2つのランドマークを訪れるようにして、休暇中に何らかの運動をするようにしています。

牛が達成できる単位時間あたりの最大の楽しみの値を見つけるのに役立ちます。

入力

*行1:スペースで区切られた2つの整数:  L  と  P
*行2 .. L +1:行  i +1には1つの整数が含まれます:  F i
*行  L +2 .. L + P +1:行  L + i +1は 、スペースで区切られた3つの整数(L 1 i  、  L 2 i  、および  T i)で牛の道iを  表します 

出力

* 1行目:小数点以下2桁に与えられた単一の数値(明示的な丸めを行わない)、単位時間あたりの最大可能平均楽しみ、または牛が上記の規則に従ってまったく旅行を計画できない場合は0。

入力例

5 7 
30 
10 
10 
5 
10 
1 2 3 
2 3 2 
3 4 5 
3 5 2 
4 5 5 
5 1 3 
5 2 2

出力例

6.00

LポイントとPエッジを持つ有向グラフが与えられた場合、各ポイントには重みFがあり、各エッジには重みTがあります。

\ frac {\ sum {F_i}} {\ sum {T_i}}最大化する回路を見つけます

2 <= L <= 1000、2 <= P <= 5000。

リングの上端はポイント数と等しいため、エッジの重みをコストとして直接取得でき、エントリポイントのポイントの重みを収入として取得できます。

次に、答えは二分され、グラフは、グラフに正のリングがあるかどうかを判断するために作成されます。それを逆にすることは否定的な判断になります。

spfaのdfaバージョンで十分です。

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <algorithm> 
#include < string .h> 
#include <vector> 
#include <math.h> 
#include <limits> 
#include < set > 
#include <map>
 using  namespace std;
#define SZ 666666
 int n、m、v [SZ]、fst [SZ]、vb [SZ]、nxt [SZ]、vc [SZ]、M = 0 、X;
bool vis [SZ]、fh = 0 ;
double dist [SZ];
a、int b、int c){++ M; nxt [M] = fst [a]; fst [a] = M; vb [M] = b; vc [M] = c;}
 void dfs(int p、double x)
{ 
    vis [p] = 1 ;
    forint e = fst [p]; e; e = nxt [e])
    { 
        double C = v [vb [e]]-x * vc [e];
        if(dist [vb [e]]> = C + dist [p])続行;
        if(vis [vb [e]]){fh = 1 ; return ;} 
        dist [vb [e]] = C + dist [p]; 
        dfs(vb [e]、x); 
        もし(fh)戻る; 
    } 
    vis [p] = 0 ; 
} 
bool ok(double x)
{ 
    forint i = 1 ; i <= n; i ++)vis [i] = dist [i] = 0 ; 
    fh = 0 ;
    forint i = 1 ; i <= n; i ++ 
    { 
        dfs(i、x); 
        if(fh)return  1 ; 
    } 
    0を返し ます
} 
int main()
{ 
    scanf("%d%d "、&​​n、&m);
     forint i = 1 ; i <= n; i ++)scanf(" %d "、v + i);
     forint i = 1 ; i <= m; i ++ 
    { 
        int a、b、c; 
        scanf(" %d%d%d "、&​​a、&b、&c); 
        adde(a、b、c); 
    } 
    double l = 0、r = 1000000000 ;
     while(rl > 1e- 6 
    { 
        double mid =(l + r)/ 2;
        if(ok(mid))l = mid; それ以外の場合、 r = mid; 
    } 
    printf(" %.2lf \ n " 、l); 
}

オリジナルhttps://blog.csdn.net/mosquito_zm/article/details/78585094

おすすめ

転載: www.cnblogs.com/xxxsans/p/12673940.html