題意:乙個無向圖,每條邊有兩個權值,h和l,要求乙個生成樹,使得所有邊的h的和比上l的和最小。
設x[i]等於1或0, 表示邊e[i]是否屬於生成樹.
則我們所求的比率 r = ∑(benifit[i] * x[i]) / ∑(cost[i] * x[i]), 0≤i為了使 r 最小, 設計乙個子問題---> 讓 z = ∑(benifit[i] * x[i]) - k * ∑(cost[i] * x[i]) = ∑(d[i] * x[i]) 最小 (d[i] = benifit[i] - k * cost[i]) , 並記為z(k). 我們可以把z(k)看做以d為邊權的最小生成樹的總權值.(如果求r最大應該使用最大生成樹).
由於cost[i]>0,所以k增大則z減小,z在k上單調遞減。
接下來便是二分k
當z<0,即k>∑(benifit[i] * x[i])/∑(cost[i] * x[i]).而我們要求k盡量大z才會小,這樣k無上限,矛盾。
故z應》=0,由於z在k上單調遞減,所以要使r最小,則z要最小,則k要最大,k不能大到使z<0,所以k最大大到使z=0.
二分k使z=0即可。
1 #include2 #include3 #include4 #include5 #include6using
namespace
std;
7struct
node
8p[1100
];11
double g[1100][1100],l[1100][1100],h[1100][1100
];12
double dis(double x1,double y1,double x2,double
y2)13
16const
double mmax=1
<<30;17
double prim(int
n)18
28int num=0;29
double sum=0;30
while(num1)31
41}42 vis[vx]=1
;43 num++;
44 sum+=g[vx][pre[vx]];
45for(i=1;i<=n;i++)
4652}53
}54return
sum;55}
56int
main()
5773
else
7482}83
}84double ll=minh/maxl;
85double rr=maxh/minl;
86while(rr-ll>1e-4)87
96 printf("
%.3f\n
",ll);97}
98return0;
99 }
poj2728 最優比率生成樹
這個題的意思是給你乙個連通圖,圖上每個點都有連個權值ai,bi讓你選乙個生成樹使得sigma ai xi sigma bi xi 最小,對比與基礎的01規劃,我們假設答案是mid,然後建立乙個圖,其新的邊的權值是ai mid bi,然後求解最小生成樹,假設其答案是tp,如果tp 0,說明還有更優的解...
poj 2728 最優比率生成樹
思路 設sum cost i sum dis i r 那麼要使r最小,也就是minsum cost i r dis i 那麼就以cost i r dis i 為邊權重新建邊。當求和使得最小生成樹的 sum cost i r dis i 0時,這個r就是最優的。這個證明是01分數規劃。include ...
POJ2728 最優比率生成樹
一張 n 個結點 m 條邊的無向圖,每條邊有兩個權值 a,b 求一顆生成樹滿足樹上的所有邊 a 權和與 b 權和的商最大。1 n,m 1e4 0 1分數規劃 從長度為 n 的數列 和 中選出若干對,使得選出的 a 之和與 b 之和商最大。即求一組 x i 1 i n,x i 0 or 1 最大化 f...