版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/FZHvampire/article/details/51700827
3597: [Scoi2014]方伯伯运椰子
Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 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
答案要求一个分数,肯定要先分数规划。
从题目中说的可以看出,起点只向外连一条边,也就是说这个图的流量是守恒的。
那么压缩就相当于退流,扩容就是增广。
化一下给的式子:
上面式子中的
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define D 5990
const int N=6000;
const int M=10000;
double dis[N];
bool f[N],flag;
struct S{int st,en;double va;}aa[M];
int n,m,tot,point[N],next[M],l[N],cnt[N];
struct Line{int st,en,a,b,c,d;}e[N];
#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);
}