[bzoj3597][SCOI2014]方伯伯运椰子
2016-06-17 16:18
351 查看
3597: [Scoi2014]方伯伯运椰子
Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 353 Solved: 215
[Submit][Status][Discuss]
Description
Input
第一行包含二个整数N,M
接下来M行代表M条边,表示这个交通网络
每行六个整数,表示Ui,Vi,Ai,Bi,Ci,Di
接下来一行包含一条边,表示连接起点的边
Output
一个浮点数,保留二位小数。表示答案,数据保证答案大于0
Sample Input
5 10 1 5 13 13 0 412 2 5 30 18 396 148 1 5 33 31 0 39 4 5 22 4 0 786 4 5 13 32 0 561 4 5 3 48 0 460 2 5 32 47 604 258 5 7 44 37 75 164 5 7 34 50 925 441 6 2 26 38 1000 22
Sample Output
103.00
HINT
1<=N<=5000 0<=M<=3000 1<=Ui,Vi<=N+2 0<=Ai,Bi<=500 0<=Ci<=10000 0<=Di<=1000
答案要求一个分数,肯定要先分数规划。
从题目中说的可以看出,起点只向外连一条边,也就是说这个图的流量是守恒的。
那么压缩就相当于退流,扩容就是增广。
化一下给的式子:x−yk>mid
x−y−mid∗k>0
y−x+mid∗k<0
上面式子中的y就是扩容的费用,x就是压缩的费用。因为有mid的影响,所以给每条边都加上mid,用SPFA找复权环就行。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define D 5990 const int N=6000; const int M=10000; double dis ; bool f ,flag; struct S{int st,en;double va;}aa[M]; int n,m,tot,point ,next[M],l ,cnt ; struct Line{int st,en,a,b,c,d;}e ; #define inf 1e9 #define eps 1e-6 #define mid (l+r)/2 inline void add(int x,int y,double z){ //printf("%d %d %.4f\n",x,y,z); next[++tot]=point[x];point[x]=tot; aa[tot].st=x;aa[tot].en=y;aa[tot].va=z; } inline void SPFA(int x){ int h=0,t=1,u,i; for(i=1;i<=n;++i) dis[i]=inf,cnt[i]=0,f[i]=true; dis[x]=0.;l[t]=x;++cnt[x]; while(h!=t){ h=h%D+1;u=l[h];f[u]=true; for(i=point[u];i;i=next[i]) if(dis[aa[i].en]>dis[u]+aa[i].va+eps){ dis[aa[i].en]=dis[u]+aa[i].va; if(f[aa[i].en]){ if(++cnt[aa[i].en]>n){ flag=false; return ; } t=t%D+1; l[t]=aa[i].en; f[aa[i].en]=false; } } } } inline bool check(double x){ int i; tot=0; memset(point,0,sizeof(point)); for(i=1;i<=m;++i){ if(e[i].st==n-1) continue; add(e[i].st,e[i].en,(double)e[i].b+(double)e[i].d+x); if(e[i].c!=0) add(e[i].en,e[i].st,(double)e[i].a-(double)e[i].d+x); } flag=true;SPFA(n); return flag==false; } int main(){ int i; scanf("%d%d",&n,&m); for(n+=2,i=1;i<=m;++i) scanf("%d%d%d%d%d%d",&e[i].st,&e[i].en,&e[i].a,&e[i].b,&e[i].c,&e[i].d); double l=0,r=inf,ans=0; while(l+eps<r){ if(check(mid)) ans=max(ans,mid),l=mid; else r=mid; } printf("%.2f\n",ans); }
相关文章推荐
- mysql服务器安装
- Java中的HashMap和Hashtable
- Linux命令查看服务器型号及SN
- Windows10修改编辑hosts文件后无法保存的解决方法【图文教程】
- Javascript函数初探
- iOS webView获取html内容
- GSM Hacking:静默短信(Silent SMS)在技术侦查中的应用 20160617
- c++--补第二次实验
- memcached完全剖析--1. memcached的基础
- 下一代Bootstrap的5个特点 超酷炫!
- Sys.dm_os_ring_buffers内幕
- 在Eclipse中使用JUnit4进行单元测试(中级篇)
- [leetcode] 360. Sort Transformed Array 解题报告
- 经历3轮百度面试的问题(iOS)
- route命令(详细)
- 使用uploadify3.2.1 formData传递其他参数到后台,JAVA后台获取参数方法
- 移动支付变巨头掘金地,银盒子手握SaaS成新宠
- FTP的主动模式和被动模式
- SQLServer如何删除字段中的某个字符串,或者替换为空格?
- 【51CTO学院三周年】-感谢恩师马哥让我成为Linux运维工程师