【01分数规划】【二分】洛谷P2868 [USACO07DEC]Sightseeing Cows G

3 篇文章 0 订阅

Link


题目


(一切如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);
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值