题目
解
(一切如tag)
二分一个比L,使在某精度下某个环内的
Σ
F
[
i
]
/
Σ
T
[
i
]
>
L
\Sigma F[i] / \Sigma T[i] > L
ΣF[i]/ΣT[i]>L
移项再乘-1,得
Σ
T
[
i
]
∗
L
−
Σ
F
[
i
]
<
0
\Sigma T[i] * L - \Sigma F[i] < 0
ΣT[i]∗L−ΣF[i]<0
于是我们将上面这条式子作边权,用spfa求负环即可得到这个比是否能得到。
代码
#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
struct asdf{
int to,zz,next;
} a[10001];
int n,p,u,v,tt,t,F[10001],l[10001],cnt[10001];
bool B[10001];
double ll,r,mid,dis[10001];
bool check(int d){
queue<int> Q;
for(int i = 1; i <= n; ++i){ //图不一定连通
Q.push(i);
dis[i] = 0;
cnt[i] = 1;
B[i] = 1;
}
while(Q.size()){
int h = Q.front();
Q.pop(); B[h] = 0;
for(int i = l[h]; i; i = a[i].next)
if(dis[a[i].to] > dis[h] + mid*a[i].zz-F[a[i].to]){
dis[a[i].to] = dis[h] + mid*a[i].zz-F[a[i].to];
if(B[a[i].to] == 0){
B[a[i].to] = 1;
Q.push(a[i].to);
if(++cnt[a[i].to] >= n) return 1;
}
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&p);
for(int i = 1; i <= n; ++i)
scanf("%d",&F[i]);
for(int i = 1; i <= p; ++i)
{
scanf("%d%d%d",&u,&v,&tt);
a[++t] = (asdf){v,tt,l[u]}; l[u] = t;
}
ll = 0; r = 100000;
while(r-ll > 0.0000001) //二分
{
mid = (ll+r)/2;
if(check(mid) == 1) ll = mid;
else r = mid - 0.0000001;
}
printf("%0.2lf",ll);
}