Title
P2868 [USACO07DEC]Sightseeing Cows G
Solution
∑ i = 1 t F [ i ] ∑ i = 1 t A [ i ] = a n s \frac{\sum_{i=1}^{t}F[i]}{\sum_{i=1}^{t}A[i]}=ans ∑i=1tA[i]∑i=1tF[i]=ans
我们可以二分 a n s ans ans
∑ i = 1 t F [ i ] − ∑ i = 1 t A [ i ] ∗ m i d > 0 \sum_{i=1}^{t}F[i]-\sum_{i=1}^{t}A[i]*mid>0 i=1∑tF[i]−i=1∑tA[i]∗mid>0
∑ i = 1 t A [ i ] ∗ m i d − ∑ i = 1 t F [ i ] < 0 \sum_{i=1}^{t}A[i]*mid-\sum_{i=1}^{t}F[i]<0 i=1∑tA[i]∗mid−i=1∑tF[i]<0
可以用 s p f a spfa spfa来判定负环。
当 r − l r-l r−l达到一定的精度后就退出
Code
#include
#include
#include
#define db double
#define rep(i,x,y) for(register int i=x;i<=y;i++)
using namespace std;
const int N=1005;
struct node{
int y,z,next;
}a[N*10];
int tot,head[N];
int n,m,b[N];
void add(int x,int y,int z){
a[++tot]=(node){y,z,head[x]}; head[x]=tot;
}
bool v[N]; db d[N]; int w[N];
bool check(db k){
queue<int>q;
rep(i,1,n) q.push(i),d[i]=0,w[i]=1,v[i]=1;
while (q.size()){
int x=q.front(); q.pop(); v[x]=0;
for(int i=head[x];i;i=a[i].next){
int y=a[i].y; db dis=(db)a[i].z;
if (d[y]>d[x]+k*dis-(db)b[x]){
d[y]=d[x]+k*dis-(db)b[x];
if (!v[y]){
q.push(y),v[y]=1;
if (++w[y]>=n) return 1;
}
}
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
rep(i,1,n) scanf("%d",&b[i]);
rep(i,1,m){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
db l=0,r=1000010,mid;
while (r-l>1e-4){
mid=(l+r)/2;
if (check(mid)) l=mid; else r=mid;
}
printf("%.2lf",l);
return 0;
}