[bzoj3597][SCOI2014]方伯伯運椰子
阿新 • • 發佈:2019-01-07
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
答案要求一個分數,肯定要先分數規劃。
從題目中說的可以看出,起點只向外連一條邊,也就是說這個圖的流量是守恆的。
那麼壓縮就相當於退流,擴容就是增廣。
化一下給的式子:
x−y−mid∗k>0
y−x+mid∗k<0
上面式子中的
#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);
}