bzoj1690[Usaco2007 Dec]奶牛的旅行*

bzoj1690[Usaco2007 Dec]奶牛的旅行

题意:

n点m边有向图,点有点权,边有边权,奶牛想要从某点出发,走一些路使得经过的点权和除以(浮点数除法)边权和最大,求这个小数(保留两位)。n≤1000,m=5000。

题解:

01分数规划!太神了,然而我看不懂证明,所以直接给出算法。假设需要所求小数最大,那么二分这个数,然后将所有边的边权改为分母(需要最小化的部分)*二分的数-分子(需要最大化的部分),然后判负环。如果有,说明解合法,否则解不合法。最后把下界输出。如果需要所求小数最小,则把边权改为分子(需要最大化的部分)-分母(需要最小化的部分)*二分的数,同时改变范围缩小的方向。

而判负环用dfs实现的spfa较快,而且每个节点都必须作为起点遍历一遍以防漏判负环。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 1010
 7 #define INF 0x3fffffff
 8 using namespace std;
 9
10 inline int read(){
11     char ch=getchar(); int f=1,x=0;
12     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
13     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
14     return f*x;
15 }
16 struct e{int t; double w; int n;}es[maxn*5]; int g[maxn],ess;
17 void pe(int f,int t){es[++ess]=(e){t,0,g[f]}; g[f]=ess;}
18 double v[maxn],w[maxn*5]; int n,m;
19 void rebuild(double x){inc(i,1,m)es[i].w=w[i]*x-v[es[i].t];}
20 bool ins[maxn],f; double d[maxn];
21 void dfs(int x){
22     ins[x]=1;
23     for(int i=g[x];i;i=es[i].n){
24         if(f)return;
25         if(d[es[i].t]>d[x]+es[i].w){
26             if(ins[es[i].t]){f=1; return;} d[es[i].t]=d[x]+es[i].w; dfs(es[i].t);
27         }
28     }
29     ins[x]=0;
30 }
31 bool spfa(){
32     memset(ins,0,sizeof(ins)); memset(d,0,sizeof(d)); f=0;
33     inc(i,1,n){dfs(i); if(f)return 0;} return 1;
34 }
35 int main(){
36     n=read(); m=read(); inc(i,1,n)v[i]=read(); inc(i,1,m){int x=read(),y=read(); w[i]=read(); pe(x,y);}
37     double l=1,r=10000;
38     while(r-l>0.001){
39         double mid=(l+r)/2; rebuild(mid); if(!spfa())l=mid;else r=mid;
40     }
41     printf("%.2lf",l); return 0;
42 }

20160921

时间: 2024-12-19 19:44:37

bzoj1690[Usaco2007 Dec]奶牛的旅行*的相关文章

bzoj1690:[Usaco2007 Dec]奶牛的旅行(分数规划+spfa判负环)

前段时间准备省选没更,后段(?)时间省选考砸没心情更,最近终于开始恢复刷题了... 题目大意:有n个点m条有向边的图,边上有花费,点上有收益,点可以多次经过,但是收益不叠加,边也可以多次经过,但是费用叠加.求一个环使得收益和/花费和最大,输出这个比值. 显然这就是经典的分数规划题啊,就是最优比率环,那么就二分答案,将所有边(u,v)的边权改为[v的点权-(u,v)原边权*mid],这可以算是最优比率环的公式了吧,然后判一下是否有正环,有的话就说明答案可行.判正环有够别扭的,那就全部改成相反数然后

【BZOJ 1690】 [Usaco2007 Dec]奶牛的旅行

1690: [Usaco2007 Dec]奶牛的旅行 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 622  Solved: 327 [Submit][Status] Description 作为对奶牛们辛勤工作的回报,Farmer John决定带她们去附近的大城市玩一天.旅行的前夜,奶牛们在兴奋地讨论如何最好地享受这难得的闲暇. 很幸运地,奶牛们找到了一张详细的城市地图,上面标注了城市中所有L(2 <= L <= 1000)座标志性建筑物(建筑

【bzoj1690】[Usaco2007 Dec]奶牛的旅行 分数规划+Spfa

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

bzoj1690:[Usaco2007 Dec]奶牛的旅行 (分数规划 &amp;&amp; 二分 &amp;&amp; spfa)

用dfs优化的spfa判环很快啦 分数规划的题目啦 二分寻找最优值,用spfa判断能不能使 Σ(mid * t - p) > 0 最优的情况只能有一个环 因为如果有两个环,两个环都可以作为奶牛的行程,如果两个环单独计算的结果不一样,那么两个环中比值更大的才是最优解,如果结果一样,多算一个环就没有意义了. 代码如下 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 using namespa

bzoj 1690: [Usaco2007 Dec]奶牛的旅行——分数规划+spfa判负环

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

BZOJ 1690: [Usaco2007 Dec]奶牛的旅行

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

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

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

[Usaco2007 Dec][BZOJ1690] 奶牛的旅行|分数规划|二分|SPFA

1690: [Usaco2007 Dec]奶牛的旅行 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 700  Solved: 363[Submit][Status][Discuss] Description 作为对奶牛们辛勤工作的回报,Farmer John决定带她们去附近的大城市玩一天.旅行的前夜,奶牛们在兴奋地讨论如何最好地享受这难得的闲暇. 很幸运地,奶牛们找到了一张详细的城市地图,上面标注了城市中所有L(2 <= L <= 1000)座标志

bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换*&amp;&amp;bzoj1692[Usaco2007 Dec]队列变换*

bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换 bzoj1692[Usaco2007 Dec]队列变换 题意: 有一个奶牛队列.每次可以在原来队列的首端或是尾端牵出一头奶牛,把她安排到新队列的尾部,然后对剩余的奶牛队列重复以上的操作,直到所有奶牛都被插到了新的队列里.这样得到的队列,就是FJ拉去登记的最终的奶牛队列. 求对于给定的奶牛们的初始位置,计算出可能得到的字典序最小的队列.队列大小≤30000. 题解: 有一个结论:如果当前队列中的队首元素不等于队尾元