1. 程式人生 > >Coding Contest HDU - 5988(費用流)

Coding Contest HDU - 5988(費用流)

\n art bsp true 價值 連接 %d print ret

題意:

  有n個區域和m條路,每個區域有a[i]個人和b[i]個食物,然後是m條路連接兩個區域,這條路容量為cap,這條路斷掉的概率為p,第一個經過的時候一定不會斷,後面的人有概率p會斷,現在需要所有人都吃上飯並且破壞網絡的概率最小

解析:

  多源多匯,建一個超級源指向食物多的 超級匯指向人多的 概率為價值 板子裏的價值都是加 所以化成log形式就好了 最後在化回來

求的是最小被破壞的概率,那麽1 - 最大被破壞的概率就好了 費用流是價值最小 給價值加個符號 不就是最大了嘛

代碼來自 :https://blog.csdn.net/Nemaleswang/article/details/77870967

改成了我喜歡寫的形式,為什麽不貼我的。。。。。emm。。。明明寫的好看。。。為啥我的T

生活失去了希望

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using
namespace std; const int INF = 0x3f3f3f3f; const int maxn = 205; const int MaxEdge = 40005; const double eps = 1e-8; int max_flow; double value; struct Edge{ int to,vol,next; double cost; }Node[MaxEdge]; int Pre[maxn],Path[maxn],Head[maxn],cnt, f[maxn]; double Dist[maxn]; bool vis[maxn]; void addedge(int
u, int v, int vol, double cost){ Node[cnt].to = v; Node[cnt].vol = vol; Node[cnt].cost = cost; Node[cnt].next = Head[u]; Head[u] = cnt++; Node[cnt].to = u; Node[cnt].vol = 0; Node[cnt].cost = -cost; Node[cnt].next = Head[v]; Head[v] = cnt++; } bool Spfa(int s, int t){ for(int i = 0;i < maxn;i++) Dist[i] = INF*1.0; memset(Pre, -1, sizeof(Pre)); memset(vis, false, sizeof(vis)); Dist[s] = 0.0; queue<int>Q; vis[s] = true; Q.push(s); f[s] = INF; while (!Q.empty()){ int u = Q.front(); Q.pop(); vis[u] = false; for (int e = Head[u]; e != -1; e = Node[e].next){ int v = Node[e].to; if (Node[e].vol > 0 && Dist[v] - Dist[u] - Node[e].cost > eps){ Dist[v] = Dist[u] + Node[e].cost; Pre[v] = u; Path[v] = e; f[Node[e].to] = min(f[u], Node[e].vol); if(!vis[v]){ vis[v] = true; Q.push(v); } } } } if(Pre[t] == -1) return 0; int u, v, e; for(u = t; u != s; u = Pre[u]){ e = Path[u]; Node[e].vol -= f[t]; Node[e^1].vol += f[t]; } max_flow += f[t]; value += (double)f[t]*Dist[t]; return 1; } void MCMF(int s, int t) { max_flow = 0; value = 0; while(Spfa(s, t)); } void init(){ memset(Head,-1,sizeof(Head)); cnt = 0; } int main(){ int t,n,m,a[maxn],b[maxn],c[maxn]; int u,v,cap; double p; scanf("%d",&t); while(t--){ init(); scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++){ scanf("%d%d",&a[i],&b[i]); c[i] = a[i]-b[i]; } while(m--){ scanf("%d%d%d%lf",&u,&v,&cap,&p); p = -log2(1.0-p); if(cap > 0) addedge(u,v,1,0.0); if(cap-1 > 0) addedge(u,v,cap-1,p); } for(int i = 1;i <= n;i++){ if(c[i] > 0) addedge(0,i,c[i],0.0); else if(c[i] < 0) addedge(i,n+1,-c[i],0.0); } MCMF(0,n+1); double ans = pow(2,-value); printf("%.2f\n",1.0-ans); } return 0; }

Coding Contest HDU - 5988(費用流)