HDU 5988 题目链接
很容易想到的是最大流最小费用例子,但是呢,先不说一直TLE的原因,怎么才能把的最小值给求出来呢,其实就是相当于去求的最大值,但是网络流解决的是和的形式,怎样去解决呢?直接上log吧!变成了的最大值,如此,不如再取个负号,变成求的最大值了,那么就是可以用最小费用流来求解了。最后得到的MaxFlow_MinCost要去做1-pow(2, MaxFlow_MinCost)变回原来的乘积形式。
当然,只有这么一个点是远远不够的!会发现,得到的答案会T,那是因为再跑流的判断的时候,我们用比较函数,一般是写成dist[v] > dist[u] + c就可以了吧、或者是势函数形式下的dist[v] > dist[u] + c + h[u] - h[v]来进行是否需要进队的运算的,但是这样的可能会存在环,原因在于这里是小数。那么,我们可以加入一个极小值efs来改变这个情况。
dist[v] > dist[u] + c + h[u] - h[v] + efs
或者是
dist[v] > dist[u] + c + efs
就可以解决这样的TLE问题了,并且以后需要牢牢的记住了!
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
//#define INF 0x3f3f3f3f
#define efs 1e-7
#define INF 1e9 + 7.
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 107, S = 0;
int N, M, ED;
struct Eddge
{
int nex, u, v, flow;
double cost;
Eddge(int _nex = -1, int _u = 0, int _v = 0, int _f = 0, double _c = 0.):nex(_nex), u(_u), v(_v), flow(_f), cost(_c) {}
};
vector<Eddge> E[maxN];
inline void _add(int u, int v, int flow, double cost)
{
E[u].push_back(Eddge((int)E[v].size(), u, v, flow, cost));
E[v].push_back(Eddge((int)E[u].size() - 1, v, u, 0, -cost));
}
struct node
{
int id; double val;
node(int a=0, double b=0.):id(a), val(b) {}
friend bool operator < (node e1, node e2) { return e1.val > e2.val; }
};
int preP[maxN], preE[maxN];
double h[maxN], dist[maxN];
priority_queue<node> Q;
inline double MaxFlow_MinCost(int Flow)
{
double ans = 0.;
for(int i=0; i<=ED; i++) h[i] = 0.;
while(Flow)
{
while(!Q.empty()) Q.pop();
for(int i=0; i<=ED; i++) dist[i] = INF;
dist[S] = 0.; Q.push(node(S, 0.));
node now;
while(!Q.empty())
{
now = Q.top(); Q.pop();
int u = now.id;
if(dist[u] < now.val) continue;
int len = (int)E[u].size();
for(int i=0, v, f; i<len; i++)
{
v = E[u][i].v; f = E[u][i].flow;
double c = E[u][i].cost;
if(f && dist[v] > dist[u] + c + h[u] - h[v] + efs)
{
dist[v] = dist[u] + c + h[u] - h[v];
preP[v] = u; preE[v] = i;
Q.push(node(v, dist[v]));
}
}
}
if(dist[ED] == INF) break;
for(int i=0; i<=ED; i++) h[i] += dist[i];
int Capa = Flow;
for(int u = ED; u; u = preP[u]) Capa = min(Capa, E[preP[u]][preE[u]].flow);
Flow -= Capa;
ans += Capa * h[ED];
for(int u = ED; u; u = preP[u])
{
Eddge &G = E[preP[u]][preE[u]];
G.flow -= Capa;
E[G.v][G.nex].flow += Capa;
}
}
return ans;
}
int main()
{
int T; scanf("%d", &T);
while(T--)
{
scanf("%d%d", &N, &M); ED = N + 1;
for(int i=0; i<=ED; i++) E[i].clear();
int sum = 0;
for(int i=1, s, b; i<=N; i++)
{
scanf("%d%d", &s, &b); sum += s;
_add(S, i, s, 0.);
_add(i, ED, b, 0.);
}
for(int i=1, u, v, f; i<=M; i++)
{
double c;
scanf("%d%d%d%lf", &u, &v, &f, &c);
_add(u, v, 1, 0.);
if(f > 1) _add(u, v, f - 1, -log2(1. - c));
}
printf("%.2lf\n", 1. - pow(2., -MaxFlow_MinCost(sum)));
}
return 0;
}