給定有點權和邊權的圖,要求找乙個環,使環的點權和與邊權和的比值最大。
此時求最大比率的式子與01規劃的式子有所不同(總算式加個負號)。
核心:取定乙個 r 值以後,帶入最短路的新的dis更新公式,再判斷是否存在至少乙個負環(找出乙個負環即可),存在負環和不存在負環兩種情況指示了 r 應如何取下乙個值,直到到達指定精度。
例題:sightseeing cows
#include
#define ll long long
#define lf double
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define debug cout<<",here\n";
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define rep(i,l,r) for(int i=(l);i< (r);i++)
#define rev(i,r,l) for(int i=(r);i>=(l);i--)
#define rev(i,r,l) for(int i=(r);i> (l);i--)
#define maxn 1005
#define inf 1e16
using
namespace std;
inline ll quickpow
(ll a,ll b,ll m)
return ans;
}int f[maxn]
;struct spfa//魔改版spfa,dis更新與傳統最短路不同
; vectornode[maxn]
;int inq[maxn]
,inq_cnt[maxn]
;double dis[maxn]
;void
init
(int n)
}void
add(
int x,
int y,
double v));
}int
spfa
(int n,
int s,
double m)
//找不出最短路,有負環
for(
auto
& i:node[now])}
}}return1;
//能找到最短路}}
;spfa spfa;
int n,m;
const
double eps=
1e-6
;int
main()
rep(i,
1,m)
double l=
0,r=
1000000.0
;//不同的問題應該取不同的初始值
while
(r-l>eps)}if
(jug) l=m;
else r=m;
}printf
("%.2lf\n"
,r);
return0;
}
參考:
最優比率環
[poj3621] sightseeing cows
poj 3621 最優比率環
思路 之前做過最小比率生成樹,也是屬於0 1整數劃分問題,這次碰到這道最優比率環,很是熟悉,可惜精度沒控制好,要不就是wa,要不就是tle,鬱悶啊!實在是懶得碼字,直接copy吧 題目的意思是 求乙個環的除以,使得那個環在所有環中除以最大。令在乙個環裡,點權為v i 對應的邊權為e i 即要求 i ...
poj3621 最優比率環
這道題的意思是給你乙個圖,有點權和邊權,你的任務是求乙個圈,使得這個圈的點權和比邊權和最大,我們依然可以使用01規劃的知識,將一條邊的權值變為ai mid bi,看看這個圖裡面有沒有正環,有的話說明還存在更優的解,這裡的正環問題可以將邊權值取反變成負環問題,如下 include include in...
最優比率生成樹
最優比率生成樹 已知乙個完全圖,每條邊有兩個引數 dis和c 求一棵生成樹,使 xi ci xi disi 最小,其中xi當第i條邊包含在生成樹中時為1,否則為0。迭代法 假設rate為當前比率,以ci rate disi作為各邊的權重,使用prim演算法構造最小生成樹,再對該最小生成樹求 xi c...