洛谷P2868 [USACO07DEC]觀光奶牛 Sightseeing Cows
題目描述
Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big city! The cows must decide how best to spend their free time.
Fortunately, they have a detailed city map showing the L (2 ≤ L ≤ 1000) major landmarks (conveniently numbered 1.. L) and the P (2 ≤ P ≤ 5000) unidirectional cow paths that join them. Farmer John will drive the cows to a starting landmark of their choice, from which they will walk along the cow paths to a series of other landmarks, ending back at their starting landmark where Farmer John will pick them up and take them back to the farm. Because space in the city is at a premium, the cow paths are very narrow and so travel along each cow path is only allowed in one fixed direction.
While the cows may spend as much time as they like in the city, they do tend to get bored easily. Visiting each new landmark is fun, but walking between them takes time. The cows know the exact fun values Fi (1 ≤ Fi ≤ 1000) for each landmark i.
The cows also know about the cowpaths. Cowpath i connects landmark L1i to L2i (in the direction L1i -> L2i ) and requires time Ti (1 ≤ Ti ≤ 1000) to traverse.
In order to have the best possible day off, the cows want to maximize the average fun value per unit time of their trip. Of course, the landmarks are only fun the first time they are visited; the cows may pass through the landmark more than once, but they do not perceive its fun value again. Furthermore, Farmer John is making the cows visit at least two landmarks, so that they get some exercise during their day off.
Help the cows find the maximum fun value per unit time that they can achieve.
作為對奶牛們辛勤工作的回報,Farmer John決定帶她們去附近的大城市玩一天。旅行的前夜,奶牛們在興奮地討論如何最好地享受這難得的閑暇。 很幸運地,奶牛們找到了一張詳細的城市地圖,上面標註了城市中所有L(2 <= L <= 1000)座標誌性建築物(建築物按1..L順次編號),以及連接這些建築物的P(2 <= P <= 5000)條道路。按照計劃,那天早上Farmer John會開車將奶牛們送到某個她們指定的建築物旁邊,等奶牛們完成她們的整個旅行並回到出發點後,將她們接回農場。由於大城市中總是寸土寸金,所有的道路都很窄,政府不得不把它們都設定為通行方向固定的單行道。 盡管參觀那些標誌性建築物的確很有意思,但如果你認為奶牛們同樣享受穿行於大城市的車流中的話,你就大錯特錯了。與參觀景點相反,奶牛們把走路定義為無趣且令她們厭煩的活動。對於編號為i的標誌性建築物,奶牛們清楚地知道參觀它能給自己帶來的樂趣值F_i (1 <= F_i <= 1000)。相對於奶牛們在走路上花的時間,她們參觀建築物的耗時可以忽略不計。 奶牛們同樣仔細地研究過城市中的道路。她們知道第i條道路兩端的建築物 L1_i和L2_i(道路方向為L1_i -> L2_i),以及她們從道路的一頭走到另一頭所需要的時間T_i(1 <= T_i <= 1000)。 為了最好地享受她們的休息日,奶牛們希望她們在一整天中平均每單位時間內獲得的樂趣值最大。當然咯,奶牛們不會願意把同一個建築物參觀兩遍,也就是說,雖然她們可以兩次經過同一個建築物,但她們的樂趣值只會增加一次。順便說一句,為了讓奶牛們得到一些鍛煉,Farmer John要求奶牛們參觀至少2個建築物。 請你寫個程序,幫奶牛們計算一下她們能得到的最大平均樂趣值。
輸入輸出格式
輸入格式:
-
Line 1: Two space-separated integers: L and P
-
Lines 2..L+1: Line i+1 contains a single one integer: Fi
- Lines L+2..L+P+1: Line L+i+1 describes cow path i with three space-separated integers: L1i , L2i , and Ti
輸出格式:
- Line 1: A single number given to two decimal places (do not perform explicit rounding), the maximum possible average fun per unit time, or 0 if the cows cannot plan any trip at all in accordance with the above rules.
輸入輸出樣例
輸入樣例#1: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輸出樣例#1:
6.00
圖論 分數規劃 最優比率環
試圖確認一下自己還會不會這麽個東西
確認的結果是已經不會了(cry)
設一段路程的收益是F,花費是dis,則比率為$\frac{\sum F}{\sum dis}=r$ ,我們要找出最大的r
二分答案r,將每條邊的邊權修改為 “目的地的收益f - 邊長度dis*r”,然後SPFA檢查圖上是否有負環,有負環則r可以增大。
SPFA找環要用DFS
SPFA 之後記得還原vis[]
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 using namespace std; 7 const double eps=1e-5; 8 const int mxn=100010; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 13 return x*f; 14 } 15 struct edge{ 16 int v,nxt,w; 17 double c; 18 }e[mxn<<1]; 19 int hd[mxn],mct=0; 20 void add_edge(int u,int v,int w){ 21 e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;e[mct].w=w;return; 22 } 23 bool vis[mxn]; 24 double dis[mxn]; 25 bool SPFA(int u){ 26 vis[u]=1; 27 for(int i=hd[u];i;i=e[i].nxt){ 28 int v=e[i].v; 29 if(dis[v]>dis[u]+e[i].c){ 30 dis[v]=dis[u]+e[i].c; 31 if(vis[v] || SPFA(v)){ 32 vis[u]=0;return 1; 33 } 34 } 35 } 36 vis[u]=0; 37 return 0; 38 } 39 int n,m; 40 int f[mxn]; 41 void restore(double r){ 42 for(int i=1;i<=mct;i++) 43 e[i].c=(double)e[i].w*r-f[e[i].v]; 44 return; 45 } 46 bool check(){ 47 for(int i=1;i<=n;i++) 48 if(SPFA(i))return 1; 49 return 0; 50 } 51 int main(){ 52 // freopen("testdata.in","r",stdin); 53 int i,j; 54 int u,v,w; 55 n=read();m=read(); 56 for(i=1;i<=n;i++) 57 f[i]=read(); 58 for(i=1;i<=m;i++){ 59 u=read();v=read();w=read(); 60 add_edge(u,v,w); 61 } 62 double l=0,r=100000; 63 while(r-l>eps){ 64 double mid=(l+r)/2; 65 restore(mid); 66 if(check()){ 67 l=mid; 68 }else r=mid; 69 } 70 printf("%.2f\n",l); 71 return 0; 72 }
洛谷P2868 [USACO07DEC]觀光奶牛 Sightseeing Cows