题目链接:
Coding ContestTime Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
For the i-th path, the wires have been stabilized at first and the first competitor who walker through it would not break the wires. Since then, however, when a person go through the i - th path, there is a chance of pi to touch
the wires and affect the whole networks. Moreover, to protect these wires, no more than ci competitors are allowed to walk through the i-th path.
Now you need to find a way for all competitors to get their lunch, and minimize the possibility of network crashing.
For each test case, the first line consists of two integers N (N ≤ 100) and M (M ≤ 5000). Each of the next N lines contains two integers si and bi (si , bi ≤ 200).
Each of the next M lines contains three integers ui , vi and ci(ci ≤ 100) and a float-point number pi(0 < pi < 1).
It is guaranteed that there is at least one way to let every competitor has lunch.
#include <bits/stdc++.h> using namespace std; const int maxn=500; const double inf=1e9; const double eps=1e-8; struct Edge { int from,to,cap,flow; double cost; }; int n,m,s,t,M; std::vector<int> G[maxn]; std::vector<Edge> edge; int inq[maxn],a[maxn],p[maxn]; double d[maxn]; inline void add_edge(int from,int to,int cap,double cost) { edge.push_back((Edge){from,to,cap,0,cost}); edge.push_back((Edge){to,from,0,0,-cost}); m=edge.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool bellmanford(int &flow,double &cost) { for(int i=0;i<=t+1;i++)d[i]=inf; memset(inq,0,sizeof(inq)); d[s]=0;inq[s]=1;p[s]=0;a[s]=inf; queue<int>qu; qu.push(s); while(!qu.empty()) { int fr=qu.front();qu.pop(); inq[fr]=0; int len=G[fr].size(); for(int i=0;i<len;i++) { Edge& e=edge[G[fr][i]]; if(e.cap>e.flow&&d[e.to]>d[fr]+e.cost+eps) { d[e.to]=d[fr]+e.cost; p[e.to]=G[fr][i]; a[e.to]=min(a[fr],e.cap-e.flow); if(!inq[e.to]){qu.push(e.to);inq[e.to]=1;} } } } if(d[t]>=inf)return false; flow+=a[t]; cost+=d[t]*a[t]; int u=t; while(u!=s) { edge[p[u]].flow+=a[t]; edge[p[u]^1].flow-=a[t]; u=edge[p[u]].from; } return true; } double mincostflow() { int flow=0;double cost=0; while(bellmanford(flow,cost)); return cost; } int main() { int T; scanf("%d",&T); while(T--) { int u,v,w; double xp; scanf("%d%d",&n,&M); s=0,t=n+1; edge.clear(); for(int i=0;i<=t;i++)G[i].clear(); for(int i=1;i<=n;i++) { scanf("%d%d",&u,&v); add_edge(s,i,u,0.0); add_edge(i,t,v,0.0); } for(int i=1;i<=M;i++) { scanf("%d%d%d%lf",&u,&v,&w,&xp); xp=-log(1-xp); add_edge(u,v,w-1,xp); add_edge(u,v,1,0.0); } //cout<<"&&&&\n"; double ans=-mincostflow(); printf("%.2f\n",1-exp(ans)); } return 0; }