https://vjudge.net/contest/201468#problem/G
一道费用流,原版来自通酱,被zzb魔改为可用于费用为double
http://www.cnblogs.com/autsky-jadek/p/4149096.html
#include<cstdio>
#include <iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define MAXN 111
#define MAXM 22001
#define INF 2147483647
int S,T,n,m;
int en,u[MAXM],v[MAXM],first[MAXN],nex[MAXM],cap[MAXM];
double cost[MAXM];//Next Array
bool inq[MAXN];
double d[MAXN]/*spfa*/;
int p[MAXN]/*spfa*/,a[MAXN]/*可改进量*/;
queue<int>q;
void Init_MCMF(){memset(first,-1,sizeof(first));en=0;}
void AddEdge(const int &U,const int &V,const int &W,const double &C)
{
u[en]=U; v[en]=V; cap[en]=W; cost[en]=C;
nex[en]=first[U]; first[U]=en++;
u[en]=V; v[en]=U; cap[en]=0; cost[en]=-C;
nex[en]=first[V]; first[V]=en++;
}
bool check[ MAXN ];
bool Spfa(int &Flow,double &Cost)
{
memset(check , 0 ,sizeof( check ) );
bool op=0;
memset(inq,0,sizeof(inq));
d[S]=0; inq[S]=1; p[S]=0; a[S]=INF; q.push(S);
check[S]=1;
while(!q.empty())
{
int U=q.front(); q.pop(); inq[U]=0;
for(int i=first[U];i!=-1;i=nex[i])
if(cap[i] && ( ( check[v[i]]==0)|| ( d[v[i]] > 1e-7+ d[U]+cost[i] ) ) )
{
d[v[i]]=d[U]+cost[i];
check[v[i]]=1;
p[v[i]]=i;
a[v[i]]=min(a[U],cap[i]);
if ( v[i] == T )
op=1;
if(!inq[v[i]]) {q.push(v[i]); inq[v[i]]=1;}
}
}
if ( op==0 )
return 0;
//if( fabs( d[T] - 2000000000)<1e-5 )return 0;
Flow+=a[T]; Cost+=d[T]*a[T]; int U=T;
while(U!=S)
{
cap[p[U]]-=a[T]; cap[p[U]^1]+=a[T];
U=u[p[U]];
}
return 1;
}
double Mincost()
{
int Flow=0;
double Cost=0;
while(Spfa(Flow,Cost));
//printf("%d\n",Flow);
return Cost;
}
void doit(){
Init_MCMF();
scanf("%d%d",&n,&m);
S=n+1;T=n+2;
for (int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
AddEdge(S,i,a,0);
AddEdge(i,T,b,0);
}
for (int i=1;i<=m;i++)
{
int a,b,c;
double d;
scanf("%d%d%d%lf",&a,&b,&c,&d);
if ( c )
{
d=-log(1-d);
//cout<<d<<endl;
if ( c>1)
AddEdge(a,b,c-1,d);
AddEdge(a,b,1,0);
}
}
printf("%.2f\n",1-exp( -Mincost() ) );
}
int main(){
int T;
scanf("%d",&T);
for (int i=1;i<=T;i++)
doit();
return 0;
}