【poj3621】最优比率环

题意:

给定n个点,每个点有一个开心度F[i],每个点有m条单向边,每条边有一个长度d,要求一个环,使得它的 开心度的和/长度和 这个比值最大。
n<=1000,m<=5000

题解:

最优比率环,很像以前做过的一题最优比率生成树。
首先二分一个答案r=sigma(xi*fi)/sigma(xi*di),设z=r*sigma(xi*di)-sigma(xi*fi),若能找到一个环满足z<=0,则代表sigma(xi*fi)>=r*sigma(xi*di),则r可以比当前的r要大,则l=mid;否则r=mid;
判断能否有一个环满足让z<=0,我们就让所有的边权=r*di-f[a[i].x],然后用spfa判负环即可。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<vector>
 8 #include<cmath>
 9 using namespace std;
10
11 const int N=1100,M=5100;
12 const double INF=(double)1e9;
13 int n,m,len,first[N],cnt[N];
14 double dis[N],F[N];
15 bool in[N];
16 struct node{
17     int x,y,next;
18     double d,w;
19 }a[2*M];
20 queue<int> q;
21
22 double mid;
23
24 double myabs(double x){return x>0 ? x:-x;}
25
26 void ins(int x,int y,double d)
27 {
28     a[++len].x=x;a[len].y=y;a[len].d=d;
29     a[len].next=first[x];first[x]=len;
30 }
31
32 double spfa(int st)
33 {
34     while(!q.empty()) q.pop();
35     for(int i=1;i<=n;i++) dis[i]=INF;
36     memset(cnt,0,sizeof(cnt));
37     memset(in,0,sizeof(in));
38     q.push(st);dis[st]=0;in[st]=1;
39     while(!q.empty())
40     {
41         int x=q.front();in[x]=0;cnt[x]++;q.pop();
42         if(cnt[x]==n) return 1;
43         for(int i=first[x];i;i=a[i].next)
44         {
45             int y=a[i].y;
46             if(dis[y]>=dis[x]+a[i].w)
47             {
48                 dis[y]=dis[x]+a[i].w;
49                 if(!in[y]) in[y]=1,q.push(y);
50             }
51         }
52     }
53     return 0;
54 }
55
56 bool check(double r)
57 {
58     for(int i=1;i<=len;i++) a[i].w=r*a[i].d-F[a[i].x];
59     return spfa(1);
60 }
61
62 int main()
63 {
64     freopen("a.in","r",stdin);
65     scanf("%d%d",&n,&m);
66     len=0;
67     memset(first,0,sizeof(first));
68     double l=0,r=0;
69     for(int i=1;i<=n;i++)
70     {
71         scanf("%lf",&F[i]);
72         r+=F[i];
73     }
74     for(int i=1;i<=m;i++)
75     {
76         int x,y;double d;
77         scanf("%d%d%lf",&x,&y,&d);
78         ins(x,y,d);
79     }
80     while(l<r)
81     {
82         mid=(l+r)/2;
83         if(check(mid)) l=mid;
84         else r=mid;
85         if(myabs(l-r)<=0.0000001) break;
86     }
87     mid=6.0;
88     if(myabs(l)<=0.0000001) printf("0\n");
89     else printf("%.2lf\n",l);
90     return 0;
91 }
时间: 2024-10-25 14:54:03

【poj3621】最优比率环的相关文章

[转]01分数规划算法 ACM 二分 Dinkelbach 最优比率生成树 最优比率环

01分数规划 前置技能 二分思想最短路算法一些数学脑细胞?问题模型1 基本01分数规划问题 给定nn个二元组(valuei,costi)(valuei,costi),valueivaluei是选择此二元组获得的价值(非负),costicosti是选择此二元组付出的代价(非负),设xi(xi∈{0,1})xi(xi∈{0,1})代表第ii个二元组的选与不选,最大(小)化下式 maximize(or minimize)   r=∑valuei?xi∑costi?ximaximize(or minim

POJ3621 Sightseeing Cows 最优比率环 二分法

题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10552   Accepted: 3613 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big ci

(最优比率环) poj3621

Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8197   Accepted: 2750 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big city! The cows must decide how best to

【bzoj1690/Usaco2007 Dec】奶牛的旅行——分数规划 最优比率环

Description 作为对奶牛们辛勤工作的回报,Farmer John决定带她们去附近的大城市玩一天.旅行的前夜,奶牛们在兴奋地讨论如何最好地享受这难得的闲暇. 很幸运地,奶牛们找到了一张详细的城市地图,上面标注了城市中所有L(2 <= L <= 1000)座标志性建筑物(建筑物按1..L顺次编号),以及连接这些建筑物的P(2 <= P <= 5000)条道路.按照计划,那天早上Farmer John会开车将奶牛们送到某个她们指定的建筑物旁边,等奶牛们完成她们的整个旅行并回到出

POJ 3621 Sightseeing Cows [最优比率环]

感觉去年9月的自己好$naive$ http://www.cnblogs.com/candy99/p/5868948.html 现在不也是嘛 裸题,具体看学习笔记 二分答案之后判负环就行了 $dfs$版超快 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; typed

POJ2728最优比率生成树解题报告

题目描述: David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels all over his country to bring water to every village. Villages which are connected to his capital village will be water

(最优比例环)POJ 3621 - Sightseeing Cows

题意: 在一个有向加权图中找到一个环,使这个环点权和/边权和 最大 分析: 一开始还没做过最优比率生成树,但是看到过,两题都A不了. 后来看了题解,索性一起撸掉. 这题可以用类似最优比率生成树的方法做,二分答案. 具体: 这个题解讲的很详细了. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue

最优比率生成树

最优比率生成树题意与最小生成树基本相同,但由单一边权的最小值转化为第一边权的总和与第二边权的总和比值的最小值,这导致算法发生巨大变化,以致于需要采用二分的方法,并进行一系列复杂的判定……(好吧,是我看来)    对于给定的有向图,要求求出一颗子树G,使其各边收益总和与花费的总和比值尽可能小,即Σ(benifit[i])/Σ(cost[i]) i∈G,我们可以二分答案λ的上下界[0,∞)(事实上上界取2^就好了),当λ为最优解时f(λ)=Σ(benifit[i])-λ*Σ(cost[i])=Σ(d

POJ 3621 Sightseeing Cows(最优比例环+SPFA检测)

Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10306   Accepted: 3519 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big city! The cows must decide how best to