1. 程式人生 > >HDU 5988最小網絡流(浮點數)

HDU 5988最小網絡流(浮點數)

blank empty pac scanf for continue -- math !=

題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5988

哇,以前的模版一直T,加了優先隊列優化才擦邊過。

建圖很好建,概率乘法化成概率加法不會化。

技術分享

技術分享

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <queue>
  6 #include <algorithm>
  7 #include <cmath>
  8
using namespace std; 9 const int maxn = 500; 10 const int INF = 1e9; 11 double dist[maxn]; 12 int tot,head[maxn]; 13 int pv[maxn],pe[maxn]; 14 typedef pair<double,int> P; 15 double eps = 1e-6; 16 struct edge 17 { 18 int to,pre,cap; 19 double cost; 20 }e[50000]; 21 void init() 22
{ 23 tot = 0; 24 memset(head,-1,sizeof(head)); 25 } 26 void add(int from,int to,int cap,double cost) 27 { 28 e[tot].pre = head[from]; 29 e[tot].to = to; 30 e[tot].cap = cap; 31 e[tot].cost = cost; 32 head[from] = tot++; 33 } 34 void addedge(int from,int to,int cap,double
cost) 35 { 36 add(from,to,cap,cost); 37 add(to,from,0,-cost); 38 } 39 int n; 40 double min_cost_flow(int s,int t,int f,int& max_flow) 41 { 42 double ret = 0.0; 43 while(f>0) 44 { 45 priority_queue<P,vector<P>,greater<P> >q; 46 for(int i=0;i<maxn;i++) dist[i] = INF; 47 dist[s] = 0.0; 48 q.push(P(0,s)); 49 while(!q.empty()) 50 { 51 P cur = q.top(); q.pop(); 52 int v = cur.second; 53 if(dist[v]<cur.first) continue; 54 for(int i=head[v];i>=0;i=e[i].pre) 55 { 56 int to = e[i].to,cap = e[i].cap; 57 double cost = e[i].cost; 58 if(cap>0&&(dist[to]-(dist[v]+cost))>=eps) 59 { 60 pv[to] = v,pe[to] = i; 61 dist[to] = dist[v] + cost; 62 q.push(P(dist[to],to)); 63 } 64 } 65 } 66 if(fabs(dist[t]-INF)<=eps) return ret;///同一目的地,每次增廣路都是最小費用 67 ///當所有邊的流量都流凈後,即沒有殘余網絡,返回。 68 int d = f; 69 for(int v=t;v!=s;v=pv[v]) 70 { 71 d = min(d,e[pe[v]].cap); 72 } 73 f -= d; 74 max_flow += d; 75 ret += (double)d*dist[t]; ///走一單位就消耗dist[t] 76 for(int v=t;v!=s;v=pv[v]) 77 { 78 e[pe[v]].cap -= d; 79 e[pe[v]^1].cap += d; 80 } 81 } 82 return ret; 83 } 84 int main() 85 { 86 int T;scanf("%d",&T); 87 while(T--) 88 { 89 int m; 90 init(); 91 scanf("%d %d",&n,&m); 92 int s = n+1; 93 int t = n+2; 94 for(int i=1;i<=n;i++) 95 { 96 int si,bi; 97 scanf("%d %d",&si,&bi); 98 int x = si-bi; 99 if(x>0) addedge(s,i,x,0); 100 else if(x<0) addedge(i,t,-x,0); 101 } 102 int u,v,c; 103 double p; 104 for(int i=1;i<=m;i++) 105 { 106 scanf("%d %d %d %lf",&u,&v,&c,&p); 107 p = -1.0*log2(1.0-p); 108 if(c>0) 109 { 110 addedge(u,v,1,0);///第一個人不用費用 111 } 112 if(c-1>0) 113 { 114 addedge(u,v,c-1,p); 115 } 116 } 117 int max_flow = 0; 118 double cost = min_cost_flow(s,t,INF,max_flow); 119 double di = 2.0; 120 printf("%.2f\n",(1.0-pow(di,-cost))); 121 } 122 return 0; 123 }

HDU 5988最小網絡流(浮點數)