/*
hdu5988 费用流
Time:2017-10-25
Author:lcy

读完题可以推出公式,假如每条路
的概率为pi,令di=1-pi,那么最终答案目标是
max{1-d1^c1*d2^c2*...*dn^cn}
等价于求d1^c1*d2^c2*...*dn^cn的最小值。

在式子上取对数,转化为加法,可以发现是个很典型的费用流
有一点需要注意,在建边时,需要加一条容量为1,费用为0
的边,用来满足题意。

*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
#define pb(a) push_back(a)
const int MAXN=325;
const int MAXM=92005;
const double eps=1e-6;
const double INF=292929292.0;
const int INFF=2147483;
struct edge{
    int f,t,cp,fl;
	double cs;//price
    edge(int aa,int bb,int cc,int dd,double ee){
        f=aa,t=bb,cp=cc,fl=dd,cs=ee;
    }
    edge(){
    }
};
edge e[MAXM];
vector<int>g[MAXN];
bool v[MAXN];
int a[MAXN],fa[MAXN],ed,flow;
double d[MAXN];
double cost;
void add_edge(int ff,int tt,int cc,double pp){
	e[ed++]=edge(ff,tt,cc,0,pp);
	e[ed++]=edge(tt,ff,0,0,-1.0*pp);
    g[ff].push_back(ed-2);
    g[tt].push_back(ed-1);
}
bool bmf(int start,int endd){
    ms(v,false);
    fr(i,1,endd)d[i]=INF;d[start]=0;
    ms(a,0);
    queue<int>q;
    q.push(start);v[start]=true;a[start]=INFF;d[start]=0;
    while(!q.empty()){
        int t=q.front();q.pop();v[t]=false;
		//printf("t=%d\n",t);
        int sz=g[t].size();
        fr(i,0,sz-1){
            edge ne=e[g[t][i]];
            if(ne.fl<ne.cp&&d[ne.t]-(d[ne.f]+ne.cs)>eps){
                d[ne.t]=d[ne.f]+ne.cs;
                a[ne.t]=min(a[ne.f],ne.cp-ne.fl);
                fa[ne.t]=g[t][i];
                //printf("now=%d,fa=%d,fa_point=%d,d=%lf\n",ne.t,fa[ne.t],ne.f,d[ne.t]);
                if(!v[ne.t]){q.push(ne.t);v[ne.t]=true;}
            }
        }
    }
    if(!a[endd])return false;
    for(int i=endd;i!=start;i=e[fa[i]].f){
	//	printf("i=%d\n",i);
        e[fa[i]].fl+=a[endd];
        e[fa[i]^1].fl-=a[endd];
    }
    flow+=a[endd];
    cost+=d[endd]*a[endd];
    return true;
}
void min_cost(int start,int end){
    flow=cost=0;
    while(bmf(start,end));
}
int start,endd,cases,n,m;
bool pos[MAXN];
int main(){
	scfd(&cases);
	while(cases--){
		scanf("%d%d",&n,&m);
		ed=start=0,endd=n+1;
		int aa,bb;
		fr(i,1,n){
			scanf("%d%d",&aa,&bb);
			int t=aa-bb;
			if(t>0)
				add_edge(start,i,t,0);
			else
				add_edge(i,endd,-1*t,0);	
		}
		fr(i,1,m){
			int aa,bb,cc;double dd;
			scanf("%d%d%d%lf",&aa,&bb,&cc,&dd);
			add_edge(aa,bb,1,0);
			add_edge(aa,bb,cc-1,-1.0*log(1.0-dd));
		}
		min_cost(start,endd);	
		printf("%.2lf\n",1-exp(-1.0*cost));
		fr(i,0,endd)g[i].clear();
	}	
	return 0;
}

 posted on 2017-10-25 20:35  cylcy  阅读(83)  评论(0编辑  收藏  举报