我正在努力解决以下问题:
给定具有3 <= N <= 1000个顶点和3 <= M <= 1000000个边缘的有向图,您可以选择该图的简单循环并走它。当您在每个边缘处行走时,您会被问到一个问题,如果你正确回答你的钱增加了一倍,否则它减半。
假设您有D美元,并且您在边缘e_i正确回答问题的机会是p_i,那么回答该问题后的预期资金是:
2 * d P_I + 1/2(d (1-P_I))= d(1/2 + 3 * P_I / 2)
查看给定图表中是否有一个简单的循环,你可以走路,走完后你会得到的预期资金多于你开始的资金。
我的方法是使用约翰逊的算法找到所有简单的周期,然后检查是否有任何周期,预期的钱超过你开始的那个,但我一直在超时。我错过了什么吗?我是否需要进行观察,或者我应该尝试更多地优化我的代码?
答案 0 :(得分:0)
这个问题的诀窍是将其减少到负循环检测。
如果您从一个顶点开始x
金额并绕过一个周期e_1,e_2,…e_k
然后返回,那么x*f_1*f_2*…f_k
最后会f_i=(1/2+3*p(e_i)/2)
。你想要的是f_1*f_2*…f_k > 1
。但这与ln(f_1) + ln(f_2) … ln(f_k) > 0
相同。
所以制作一个边长为-ln(f_k)
的图表。然后问题减少到负循环检测,这可以使用像Bellman-Ford这样的算法来完成。