单纯性与网络流

单纯性模板:

需要b > 0, xi > 0.

 1 // 单纯性
 2 // n+1 * m+1 矩阵
 3 // 1~n 为约束 <= 右值
 4 // n+1为目标最大值
 5 // 对偶化直接转置即可
 6 const int maxn = 1100, maxm = 11000;
 7 const double eps = 1e-7, INF = 1e20;
 8 int dcmp(double a) { return fabs(a)<eps?0:a<0?-1:1; }
 9 int n , m;
10 double a[maxm][maxn];
11 void pivot(int l , int e){
12     for(int i = 1; i <= n; i++) if(i != l&&dcmp(a[i][e])){
13         for(int j = 1; j <= m; j++)
14             if(j != e) a[i][j] -= a[i][e]/a[l][e]*a[l][j];
15         a[i][e] /= -a[l][e];
16     }
17     for(int i = 1; i <= m; i++) if(i != e) a[l][i] /= a[l][e]; a[l][e] = 1/a[l][e];
18 }
19 
20 double simplex(){
21     double mn;
22     int e , l;
23     while(1){
24         for(e=1;e<m;e++) if(dcmp(a[n][e]) > 0) break;
25         if(e == m) return -a[n][m];
26         mn = INF;
27         for(int i=1;i<n;i++) if(dcmp(a[i][e]) > 0 && mn > a[i][m]/a[i][e]) mn = a[l=i][m]/a[i][e];
28         if(mn == INF) return INF;
29         pivot(l, e);
30     }
31 }
View Code

 

bzoj1061

题意:有n天,第i天需要ai个志愿者,有m类志愿者,每类志愿者工作时间为[l,r],花费为ci,求最小花费

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1100, maxm = 11000;
 5 const double eps = 1e-7, INF = 1e20;
 6 int dcmp(double a) { return fabs(a)<eps?0:a<0?-1:1; }
 7 int n , m;
 8 double a[maxm][maxn];
 9 void pivot(int l , int e){
10     for(int i = 1; i <= n; i++) if(i != l&&dcmp(a[i][e])){
11         for(int j = 1; j <= m; j++)
12             if(j != e) a[i][j] -= a[i][e]/a[l][e]*a[l][j];
13         a[i][e] /= -a[l][e];
14     }
15     for(int i = 1; i <= m; i++) if(i != e) a[l][i] /= a[l][e]; a[l][e] = 1/a[l][e];
16 }
17 
18 double simplex(){
19     double mn;
20     int e, l;
21     while(1){
22         for(e=1;e<m;e++) if(dcmp(a[n][e]) > 0) break;
23         if(e == m) return -a[n][m];
24         mn = INF;
25         for(int i=1;i<n;i++) if(dcmp(a[i][e]) > 0 && mn > a[i][m]/a[i][e]) mn = a[l=i][m]/a[i][e];
26         if(mn == INF) return INF;
27         pivot(l, e);
28     }
29 }
30 
31 int main() {
32     scanf("%d%d", &n, &m);
33     //对偶化
34     for(int i = 1; i <= n; i++)
35         scanf("%lf", &a[m+1][i]);
36     for(int i = 1, l, r, v; i <= m; i++) {
37         scanf("%d%d%d" , &l, &r, &v);
38         for(int j = l; j <= r; j++) a[i][j] = 1;
39         a[i][n+1] = v;
40     }
41     n++, m++;
42     swap(n, m);
43     printf("%d" , (int)(simplex()+0.50));
44     return 0;
45 }
View Code

 

 ======================  网络流分割线   ======================

模板

Dinic

 1 template<typename flow_t>
 2 struct Dinic{
 3     static const int N = 10010, M = 50000;
 4     int head[N], d[N];
 5     int tot, sink, source, n;
 6     struct Edge{
 7         int from, to, next;
 8         flow_t cap, flow;
 9         Edge(){}
10         Edge(int from, int to, int next, flow_t cap, flow_t flow):from(from), to(to), next(next), cap(cap), flow(flow){}
11     }edge[M];
12     void init(int n) {
13         this->n = n;
14         memset(head, -1, sizeof(head[0])*n);
15         tot = 0;
16     }
17     void AddEdge(int u, int v, flow_t cap) {
18         edge[tot] = Edge(u, v, head[u], cap, 0); head[u] = tot++;
19         edge[tot] = Edge(v, u, head[u], 0, 0); head[u] = tot++;
20     }
21     bool bfs(int s) {
22         int u, v;
23         memset(d, 0, sizeof(d[0])*n);
24         queue<int> Q;
25         Q.push(s);
26         d[s] = 1;
27         while (!Q.empty()) {
28             u = Q.front(); Q.pop();
29             if (u == sink) return true;
30             for (int i = head[u]; ~i; i = edge[i].next) {
31                 v = edge[i].to;
32                 if (!d[v]&&edge[i].cap-edge[i].flow > 0) {
33                     d[v] = d[u] + 1;
34                     Q.push(v);
35                 }
36             }
37         }
38         return false;
39     }
40     flow_t dfs(int x, flow_t a) {
41         if (x == sink || a == 0)
42             return a;
43         flow_t f, flow = 0;
44         for (int i = head[x]; ~i; i = edge[i].next) {
45             int v = edge[i].to;
46             if (d[v] == d[x] + 1 && edge[i].cap - edge[i].flow > 0) {
47                 f = dfs(v, min(a, edge[i].cap - edge[i].flow));
48                 edge[i].flow += f;
49                 edge[i^1].flow -= f;
50                 flow += f;
51                 a -= f;
52                 if (!a) break;
53             }
54         }
55         if (flow == 0) d[x] = 0;
56         return flow;
57     }
58     flow_t Maxflow(int source, int sink, flow_t need) {
59         flow_t flow = 0;
60         this->source = source;
61         this->sink = sink;
62         while (bfs(source)) {
63             flow += dfs(source, need-flow);
64             if (flow >= need) return flow;
65         }
66         return flow;
67     }
68 };
View Code

ISAP(morejarphone)

 1 template<typename type>
 2 struct Isap{//morejarphone
 3     static const int N = 10010, M = 50000;
 4     static const int INF = 0x3f3f3f3f;
 5     int tot, n, s, t;
 6     int head[N], gap[N], dep[N], pre[N], cur[N];
 7     struct Edge {
 8         int to, next;
 9         type cap, flow;
10         Edge(){}
11         Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){}
12     }edge[M];
13 
14     void init(int n){
15         this->n = n;
16         tot = 0;
17         memset(head, -1, sizeof head);
18     }
19     void add_edge(int u, int v, type w, type rw = 0){
20         edge[tot] = Edge(v, head[u], w, 0);
21         head[u] = tot++;
22         edge[tot] = Edge(u, head[v], rw, 0);
23         head[v] = tot++;
24     }
25     type sap(int s, int t){
26         this->s = s;
27         this->t = t;
28         memset(gap, 0, sizeof gap);
29         memset(dep, 0, sizeof dep);
30         memcpy(cur, head, sizeof head);
31         int u = s;
32         pre[u] = -1, gap[0] = n;
33         type ans = 0;
34         while(dep[s] < n){
35             if(u == t){
36                 type Min = INF;
37                 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
38                     Min = min(Min, edge[i].cap-edge[i].flow);
39                 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){
40                     edge[i].flow += Min;
41                     edge[i^1].flow -= Min;
42                 }
43                 u = s;
44                 ans += Min;
45                 continue;
46             }
47             bool flag = false;
48             int v;
49             for(int i = cur[u]; i != -1; i = edge[i].next){
50                 v = edge[i].to;
51                 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){
52                     flag = true;
53                     cur[u] = pre[v] = i;
54                     break;
55                 }
56             }
57             if(flag){
58                 u = v;
59                 continue;
60             }
61             int Min = n;
62             for(int i = head[u]; i != -1; i = edge[i].next)
63                 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){
64                       Min = dep[edge[i].to];
65                       cur[u] = i;
66                  }
67             if(--gap[dep[u]] == 0) break;
68             dep[u] = Min+1;
69             gap[dep[u]]++;
70             if(u != s) u = edge[pre[u]^1].to;
71         }
72         return ans;
73     }
74 };
View Code
 1 #define type int
 2 struct Edge {
 3     int to, next;
 4     type cap, flow;
 5     Edge(){}
 6     Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){}
 7 };
 8 struct Isap{
 9     Edge edge[M];
10     int tot, head[N];
11     int gap[N], dep[N], pre[N], cur[N];
12 
13     void init(){
14         tot = 0;
15         memset(head, -1, sizeof head);
16     }
17     void add_edge(int u, int v, type w, type rw = 0){
18         edge[tot] = Edge(v, head[u], w, 0);
19         head[u] = tot++;
20         edge[tot] = Edge(u, head[v], rw, 0);
21         head[v] = tot++;
22     }
23     type sap(int s, int t, int N){
24         memset(gap, 0, sizeof gap);
25         memset(dep, 0, sizeof dep);
26         memcpy(cur, head, sizeof head);
27         int u = s;
28         pre[u] = -1, gap[0] = N;
29         type ans = 0;
30         while(dep[s] < N){
31             if(u == t){
32                 type Min = INF;
33                 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
34                     Min = min(Min, edge[i].cap-edge[i].flow);
35                 for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){
36                     edge[i].flow += Min;
37                     edge[i^1].flow -= Min;
38                 }
39                 u = s;
40                 ans += Min;
41                 continue;
42             }
43             bool flag = false;
44             int v;
45             for(int i = cur[u]; i != -1; i = edge[i].next){
46                 v = edge[i].to;
47                 if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){
48                     flag = true;
49                     cur[u] = pre[v] = i;
50                     break;
51                 }
52             }
53             if(flag){
54                 u = v;
55                 continue;
56             }
57             int Min = N;
58             for(int i = head[u]; i != -1; i = edge[i].next)
59                 if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){
60                       Min = dep[edge[i].to];
61                       cur[u] = i;
62                  }
63             if(--gap[dep[u]] == 0) break;
64             dep[u] = Min+1;
65             gap[dep[u]]++;
66             if(u != s) u = edge[pre[u]^1].to;
67         }
68         return ans;
69     }
70 };
View Code

ISAP

 1 template<typename type>
 2 struct Isap{
 3     static const int N = 10010, M = 1000010;
 4     static const int INF = 0x3f3f3f3f;
 5     int tot, s, t, n;
 6     int head[N], gap[N], d[N], pre[N], cur[N];
 7     bool vis[N];
 8     struct Edge{
 9         int from, to, next;
10         type cap, flow;
11         Edge(){}
12         Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){}
13     }edge[M];
14 
15     void init(int n){
16         tot = 0;
17         this->n = n;
18         memset(head, -1, sizeof(head[0])*n);
19     }
20     void add_edge(int u, int v, type w, type rw = 0){
21         edge[tot] = Edge(u, v, head[u], w, 0);
22         head[u] = tot++;
23         edge[tot] = Edge(v, u, head[v], rw, 0);
24         head[v] = tot++;
25     }
26     void bfs(){
27         memset(d, -1, sizeof(d[0])*n);
28         memset(gap, 0, sizeof(gap));//////////////////////
29         queue<int> Q;
30         d[t] = 0, gap[0] = 1;
31         Q.push(t);
32         while(!Q.empty()){
33             int u = Q.front(); Q.pop();
34             for(int i = head[u]; i != -1; i = edge[i].next){
35                 int v = edge[i].to;
36                 if(d[v] == -1){
37                     gap[ d[v] = d[u]+1 ]++;
38                     Q.push(v);
39                 }
40             }
41         }
42     }
43     type sap(int s, int t, int need){
44         this->s = s;
45         this->t = t;
46         memcpy(cur, head, sizeof(cur[0])*n);/////////////////////////
47         type flow = 0;
48         bfs();
49         int u = pre[s] = s, i;
50         while(d[s] < n){
51             if(u == t){
52                 type f = INF;
53                 for(i = s; i != t; i = edge[ cur[i] ].to)
54                     if(f > edge[cur[i]].cap) f = edge[ cur[u = i] ].cap;
55                 flow += f;
56                 if(flow > need) return flow;
57                 for(i = s; i != t; i = edge[cur[i]].to ) {
58                     edge[cur[i]].cap -= f ;
59                     edge[cur[i]^1].cap += f ;
60                 }
61             }
62             for(i = cur[u]; ~i; i = edge[i].next)
63                 if(edge[i].cap&&d[u] == d[edge[i].to]+1) break;
64             if(~i){
65                 cur[u] = i ;
66                 pre[edge[i].to] = u;
67                 u = edge[i].to;
68             }else{
69                 if(0 == --gap[d[u]]) break ;
70                 int minv = n;
71                 for(int i = head[u]; ~i; i = edge[i].next){
72                     int v = edge[i].to;
73                     if(edge[i].cap&&minv > d[v]){
74                         minv = d[v];
75                         cur[u] = i;
76                     }
77                 }
78                 d[u] = minv + 1 ;
79                 gap[d[u]] ++ ;
80                 u = pre[u] ;
81             }
82         }
83         return flow;
84     }
85 };
View Code
 1 #define type int
 2 #define M 1000010
 3 #define N 10010
 4 #define INF 0x3f3f3f3f
 5 struct Edge{
 6     int from, to, next;
 7     type cap, flow;
 8     Edge(){}
 9     Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){}
10 };
11 int n, m, k, s, t;
12 struct Isap{
13     Edge edge[M];
14     int tot, head[N];
15     int gap[N], d[N], pre[N], cur[N];
16     bool vis[N];
17     void init(){
18         tot = 0;
19         memset(head, -1, sizeof head);
20     }
21     void add_edge(int u, int v, type w, type rw = 0){
22         edge[tot] = Edge(u, v, head[u], w, 0);
23         head[u] = tot++;
24         edge[tot] = Edge(v, u, head[v], rw, 0);
25         head[v] = tot++;
26     }
27     void bfs(){///////////////////
28         memset(d, -1, sizeof(d));
29         memset(gap, 0, sizeof(gap));
30         queue<int> Q;
31         d[t] = 0, gap[0] = 1;
32         Q.push(t);
33         while(!Q.empty()){
34             int u = Q.front(); Q.pop();
35             for(int i = head[u]; i != -1; i = edge[i].next){
36                 int v = edge[i].to;
37                 if(d[v] == -1){
38                     gap[ d[v] = d[u]+1 ]++;
39                     Q.push(v);
40                 }
41             }
42         }
43     }
44     type sap(int s, int t, int n, int need){
45         memcpy(cur, head, sizeof cur);
46         type flow = 0;
47         bfs();
48         int u = pre[s] = s, i;
49         while(d[s] < n){
50             if(u == t){
51                 type f = INF;
52                 for(i = s; i != t; i = edge[ cur[i] ].to)
53                     if(f > edge[cur[i]].cap) f = edge[ cur[u = i] ].cap;
54                 flow += f;
55                 if(flow > need) return flow;
56                 for(i = s; i != t; i = edge[cur[i]].to ) {
57                     edge[cur[i]].cap -= f ;
58                     edge[cur[i]^1].cap += f ;
59                 }
60             }
61             for(i = cur[u]; ~i; i = edge[i].next)
62                 if(edge[i].cap&&d[u] == d[edge[i].to]+1) break;
63             if(~i){
64                 cur[u] = i ;
65                 pre[edge[i].to] = u;
66                 u = edge[i].to;
67             }else{
68                 if(0 == --gap[d[u]]) break ;
69                 int minv = n;
70                 for(int i = head[u]; ~i; i = edge[i].next){
71                     int v = edge[i].to;
72                     if(edge[i].cap&&minv > d[v]){
73                         minv = d[v];
74                         cur[u] = i;
75                     }
76                 }
77                 d[u] = minv + 1 ;
78                 gap[d[u]] ++ ;
79                 u = pre[u] ;
80             }
81         }
82         return flow;
83     }
84 };
View Code

费用流模板(摘自AngryBacon)

 1 template<typename flow_t, typename cost_t>
 2 struct MCMF {
 3   static const int N = 1000, M = 50000;
 4   const flow_t inf = 1e9;
 5   struct node {
 6     int from, to, nxt;
 7     flow_t cap, flow;
 8     cost_t cost;
 9     node() {}
10     node(int from, int to, int nxt, flow_t cap, cost_t cost):
11       from(from), to(to), nxt(nxt), cap(cap), flow(0), cost(cost) {}
12   } E[M];
13   cost_t dis[N];
14   int G[N], pre[N], vis[N], n, m;
15   void init(int n) {
16     this->n = n;
17     this->m = 0;
18     std::fill(G, G + n, -1);
19   }
20   void link(int u, int v, flow_t f, cost_t c) {
21     E[m] = node(u, v, G[u], f, +c); G[u] = m++;
22     E[m] = node(v, u, G[v], 0, -c); G[v] = m++;
23   }
24   bool extand(int S, int T) {
25     std::fill(vis, vis + n, 0);
26     std::fill(dis, dis + n, inf);
27     std::queue<int> queue;
28     dis[S] = 0;
29     queue.push(S);
30     for (; !queue.empty(); queue.pop()) {
31       int u = queue.front();
32       vis[u] = false;
33       for (int it = G[u]; ~it; it = E[it].nxt) {
34         int v = E[it].to;
35         if (E[it].cap > E[it].flow && dis[v] > dis[u] + E[it].cost) {
36           dis[v] = dis[u] + E[it].cost;
37           pre[v] = it;
38           if (!vis[v]) queue.push(v);
39           vis[v] = true;
40         }
41       }
42     }
43     return vis[T]; //改成dis[T] <= 0 求可行流
44   }
45   std::pair<flow_t, cost_t> run(int S, int T) {
46     flow_t max_flow = 0;
47     cost_t min_cost = 0;
48     while (extand(S, T)) {
49       flow_t delta = inf;
50       for (int u = T; u != S; u = E[pre[u]].from) {
51         delta = std::min(delta, E[pre[u]].cap - E[pre[u]].flow);
52       }
53       min_cost += delta * dis[T];
54       max_flow += delta;
55       for (int u = T; u != S; u = E[pre[u]].from) {
56         E[pre[u]].flow += delta;
57         E[pre[u] ^ 1].flow -= delta;
58       }
59     }
60     return {max_flow, min_cost};
61   }
62 };
View Code

费用流模板(如果cost是double型,注意cost精度)

 1 struct Edge{
 2     int u, v, next, cap, flow;
 3     type cost;
 4     Edge(){}
 5     Edge(int u, int v, int next, int cap, int flow, type cost):u(u), v(v), next(next), cap(cap), flow(flow), cost(cost){}
 6 };
 7 
 8 Edge edge[maxm];
 9 int cnt, head[maxn], pre[maxn];
10 type dis[maxn];
11 bool vis[maxn];
12 
13 void init () {
14     memset (head, -1, sizeof head);
15     cnt = 0;
16 }
17 void add_edge(int u, int v, int cap, type cost) {
18     edge[cnt] = Edge(u, v, head[u], cap, 0, cost);
19     head[u] = cnt++;
20     edge[cnt] = Edge(v, u, head[v], 0, 0, -cost);
21     head[v] = cnt++;
22 }
23 bool spfa(int s, int t) {
24     queue<int> Q;
25     for(int i = 0; i < N; i++)
26         dis[i] = INF, vis[i] = 0, pre[i] = -1;
27     dis[s] = 0, vis[s] = 1;
28     Q.push(s);
29     while(!Q.empty()){
30         int u = Q.front(); Q.pop();
31         vis[u] = 0;
32         for(int i = head[u]; i != -1; i = edge[i].next){
33             int v = edge[i].v;
34             if(edge[i].cap > edge[i].flow&&dis[v] > dis[u]+edge[i].cost){//注意精度
35                 dis[v] = dis[u]+edge[i].cost;
36                 pre[v] = i;
37                 if (!vis[v]){
38                     vis[v] = 1;
39                     Q.push(v);
40                 }
41             }
42         }
43     }
44     return pre[t] != -1;
45 }
46 int MCMF(int s, int t, type &cost){
47     int flow = 0;
48     cost = 0;
49     while(spfa(s, t)){
50         int Min = INF;
51         for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){
52             if (Min > edge[i].cap-edge[i].flow)
53                     Min = edge[i].cap-edge[i].flow;
54         }
55         for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){
56             edge[i].flow += Min;
57             edge[i^1].flow -= Min;
58             cost += edge[i].cost*Min;
59         }
60         flow += Min;
61     }
62     return flow;
63 }
View Code

 

 网络流24题

 

hdu1532 裸最大流/模板测试

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define type ll
 5 const int N = 1005, M = 50005;
 6 const double INF = 1e16;
 7 int n, m;
 8 int s, t;
 9 struct Edge {
10     int to, next;
11     type cap, flow;
12     Edge(){}
13     Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){}
14 };
15 Edge edge[M];
16 int tot, head[N];
17 int gap[N], dep[N], pre[N], cur[N];
18 
19 void init(){
20     tot = 0;
21     memset(head, -1, sizeof head);
22 }
23 void add_edge(int u, int v, type w, type rw = 0){
24     edge[tot] = Edge(v, head[u], w, 0);
25     head[u] = tot++;
26     edge[tot] = Edge(u, head[v], rw, 0);
27     head[v] = tot++;
28 }
29 type sap(int s, int t, int N){
30     memset(gap, 0, sizeof gap);
31     memset(dep, 0, sizeof dep);
32     memcpy(cur, head, sizeof head);
33     int u = s;
34     pre[u] = -1, gap[0] = N;
35     type ans = 0;
36     while(dep[s] < N){
37         if(u == t){
38             type Min = INF;
39             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
40                 Min = min(Min, edge[i].cap-edge[i].flow);
41             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){
42                 edge[i].flow += Min;
43                 edge[i^1].flow -= Min;
44             }
45             u = s;
46             ans += Min;
47             continue;
48         }
49         bool flag = false;
50         int v;
51         for(int i = cur[u]; i != -1; i = edge[i].next){
52             v = edge[i].to;
53             if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){
54                 flag = true;
55                 cur[u] = pre[v] = i;
56                 break;
57             }
58         }
59         if(flag){
60             u = v;
61             continue;
62         }
63         int Min = N;
64         for(int i = head[u]; i != -1; i = edge[i].next)
65             if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){
66                   Min = dep[edge[i].to];
67                   cur[u] = i;
68              }
69         if(--gap[dep[u]] == 0) break;
70         dep[u] = Min+1;
71         gap[dep[u]]++;
72         if(u != s) u = edge[pre[u]^1].to;
73     }
74     return ans;
75 }
76 
77 int main(){
78     while(~scanf("%d%d", &n, &m)){
79         init();
80         int s, e, c;
81         for(int i = 0; i < n; i++){
82             scanf("%d%d%d", &s, &e, &c);
83             add_edge(s, e, c, 0);
84         }
85         ll ans = sap(1, m, m);
86         printf("%lld\n", ans);
87     }
88 }
View Code

 

poj1695 简单最大流

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 using namespace std;
  5 #define ll long long
  6 #define type ll
  7 const int N = 1005, M = 50005;
  8 const double INF = 1e16;
  9 int n, m;
 10 int s, t;
 11 struct Edge {
 12     int to, next;
 13     type cap, flow;
 14     Edge(){}
 15     Edge(int to, int next, type cap, type flow):to(to), next(next), cap(cap), flow(flow){}
 16 };
 17 Edge edge[M];
 18 int tot, head[N];
 19 int gap[N], dep[N], pre[N], cur[N];
 20 
 21 void init(){
 22     tot = 0;
 23     memset(head, -1, sizeof head);
 24 }
 25 void add_edge(int u, int v, type w, type rw = 0){
 26     edge[tot] = Edge(v, head[u], w, 0);
 27     head[u] = tot++;
 28     edge[tot] = Edge(u, head[v], rw, 0);
 29     head[v] = tot++;
 30 }
 31 type sap(int s, int t, int N){
 32     memset(gap, 0, sizeof gap);
 33     memset(dep, 0, sizeof dep);
 34     memcpy(cur, head, sizeof head);
 35     int u = s;
 36     pre[u] = -1, gap[0] = N;
 37     type ans = 0;
 38     while(dep[s] < N){
 39         if(u == t){
 40             type Min = INF;
 41             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
 42                 Min = min(Min, edge[i].cap-edge[i].flow);
 43             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){
 44                 edge[i].flow += Min;
 45                 edge[i^1].flow -= Min;
 46             }
 47             u = s;
 48             ans += Min;
 49             continue;
 50         }
 51         bool flag = false;
 52         int v;
 53         for(int i = cur[u]; i != -1; i = edge[i].next){
 54             v = edge[i].to;
 55             if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){
 56                 flag = true;
 57                 cur[u] = pre[v] = i;
 58                 break;
 59             }
 60         }
 61         if(flag){
 62             u = v;
 63             continue;
 64         }
 65         int Min = N;
 66         for(int i = head[u]; i != -1; i = edge[i].next)
 67             if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){
 68                   Min = dep[edge[i].to];
 69                   cur[u] = i;
 70              }
 71         if(--gap[dep[u]] == 0) break;
 72         dep[u] = Min+1;
 73         gap[dep[u]]++;
 74         if(u != s) u = edge[pre[u]^1].to;
 75     }
 76     return ans;
 77 }
 78 int day[7];
 79 int main(){
 80     int t; scanf("%d", &t);
 81     while(t--){
 82         init();
 83         scanf("%d", &n);
 84         //1 ~ n
 85         int d, w, maxw = -1, sum = 0;
 86         for(int i = 1; i <= n; i++){
 87             for(int j = 0; j < 7; j++)
 88                 scanf("%d", day+j);
 89             scanf("%d%d", &d, &w);
 90             sum += d;
 91             maxw = max(w, maxw);
 92             add_edge(0, i, d, 0);
 93             for(int j = 0; j < 7; j++) if(day[j])
 94                 for(int k = 0; k < w; k++)
 95                     add_edge(i, n+k*7+j+1, 1, 0);
 96         }
 97         int s = 0, t = n+7*maxw+1;
 98         for(int k = 0; k < maxw; k++)
 99             for(int j = 0; j < 7; j++)
100                 add_edge(n+k*7+j+1, t, 1, 0);
101         int ans = sap(s, t, t+1);
102         printf("%s\n", ans == sum?  "Yes":"No");
103     }
104 }
View Code

 

 poj3204 关键割/残量网络搜索

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 using namespace std;
  5 #define ll long long
  6 #define type ll
  7 const int N = 1005, M = 50005;
  8 const double INF = 1e16;
  9 int n, m;
 10 int s, t;
 11 struct Edge {
 12     int from, to, next;
 13     type cap, flow;
 14     Edge(){}
 15     Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){}
 16 };
 17 Edge edge[M];
 18 int tot, head[N];
 19 int gap[N], dep[N], pre[N], cur[N];
 20 
 21 void init(){
 22     tot = 0;
 23     memset(head, -1, sizeof head);
 24 }
 25 void add_edge(int u, int v, type w, type rw = 0){
 26     edge[tot] = Edge(u, v, head[u], w, 0);
 27     head[u] = tot++;
 28     edge[tot] = Edge(v, u, head[v], rw, 0);
 29     head[v] = tot++;
 30 }
 31 type sap(int s, int t, int N){
 32     memset(gap, 0, sizeof gap);
 33     memset(dep, 0, sizeof dep);
 34     memcpy(cur, head, sizeof head);
 35     int u = s;
 36     pre[u] = -1, gap[0] = N;
 37     type ans = 0;
 38     while(dep[s] < N){
 39         if(u == t){
 40             type Min = INF;
 41             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
 42                 Min = min(Min, edge[i].cap-edge[i].flow);
 43             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){
 44                 edge[i].flow += Min;
 45                 edge[i^1].flow -= Min;
 46             }
 47             u = s;
 48             ans += Min;
 49             continue;
 50         }
 51         bool flag = false;
 52         int v;
 53         for(int i = cur[u]; i != -1; i = edge[i].next){
 54             v = edge[i].to;
 55             if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){
 56                 flag = true;
 57                 cur[u] = pre[v] = i;
 58                 break;
 59             }
 60         }
 61         if(flag){
 62             u = v;
 63             continue;
 64         }
 65         int Min = N;
 66         for(int i = head[u]; i != -1; i = edge[i].next)
 67             if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){
 68                   Min = dep[edge[i].to];
 69                   cur[u] = i;
 70              }
 71         if(--gap[dep[u]] == 0) break;
 72         dep[u] = Min+1;
 73         gap[dep[u]]++;
 74         if(u != s) u = edge[pre[u]^1].to;
 75     }
 76     return ans;
 77 }
 78 
 79 int vis[N];
 80 void dfs(int s){
 81     vis[s] = 1;
 82     for(int i = head[s]; i != -1; i = edge[i].next)
 83         if(!vis[edge[i].to]&&edge[i].cap > edge[i].flow){
 84             vis[edge[i].to] = 1;
 85             dfs(edge[i].to);
 86         }
 87 }
 88 void rdfs(int t){
 89     vis[t] = 2;
 90     for(int i = head[t]; i != -1; i = edge[i].next)
 91         //edge[i].cap-edge[i].flow: edge[i].to -> edge[i].from 残量
 92         //edge[i^1].cap-edge[i^1].flow: edge[i].from -> edge[i].to 残量
 93         if(!vis[edge[i].to]&&edge[i^1].cap > edge[i^1].flow){
 94             vis[t] = 2;
 95             rdfs(edge[i].to);
 96         }
 97 }
 98 
 99 int main(){
100     init();
101     scanf("%d%d", &n, &m);
102     int a, b, c;
103     for(int i = 0; i < m; i++){
104         scanf("%d%d%d", &a, &b, &c);
105         add_edge(a, b, c);
106     }
107     sap(0, n-1, n);
108     dfs(0), rdfs(n-1);
109     int ans = 0;
110     for(int i = 0; i < tot; i += 2)
111         if(edge[i].cap == edge[i].flow&&vis[ edge[i].from ] == 1&&vis[ edge[i].to ] == 2)
112             ans++;
113     printf("%d\n", ans);
114 }
View Code

 

UVA11248 大白/保留原流量,多次修改容量求增广路

  1 //UVA11248
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <iostream>
  5 #include <vector>
  6 #include <algorithm>
  7 using namespace std;
  8 #define pii pair<int, int>
  9 #define ll long long
 10 #define type ll
 11 const int N = 1005, M = 50005;
 12 const double INF = 1e16;
 13 int n, m;
 14 int s, t;
 15 ll c;
 16 struct Edge {
 17     int from, to, next;
 18     type cap, flow;
 19     Edge(){}
 20     Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){}
 21 };
 22 Edge edge[M];
 23 int tot, head[N];
 24 int gap[N], dep[N], pre[N], cur[N];
 25 
 26 void init(){
 27     tot = 0;
 28     memset(head, -1, sizeof head);
 29 }
 30 void add_edge(int u, int v, type w, type rw = 0){
 31     edge[tot] = Edge(u, v, head[u], w, 0);
 32     head[u] = tot++;
 33     edge[tot] = Edge(v, u, head[v], rw, 0);
 34     head[v] = tot++;
 35 }
 36 type sap(int s, int t, int N, ll limit){
 37     memset(gap, 0, sizeof gap);
 38     memset(dep, 0, sizeof dep);
 39     memcpy(cur, head, sizeof head);
 40     int u = s;
 41     pre[u] = -1, gap[0] = N;
 42     type ans = 0;
 43     while(dep[s] < N){
 44         if(u == t){
 45             type Min = INF;
 46             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])
 47                 Min = min(Min, edge[i].cap-edge[i].flow);
 48             for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]){
 49                 edge[i].flow += Min;
 50                 edge[i^1].flow -= Min;
 51             }
 52             u = s;
 53             ans += Min;
 54             if(ans >= limit) return ans;
 55             continue;
 56         }
 57         bool flag = false;
 58         int v;
 59         for(int i = cur[u]; i != -1; i = edge[i].next){
 60             v = edge[i].to;
 61             if(edge[i].cap-edge[i].flow&&dep[v]+1 == dep[u]){
 62                 flag = true;
 63                 cur[u] = pre[v] = i;
 64                 break;
 65             }
 66         }
 67         if(flag){
 68             u = v;
 69             continue;
 70         }
 71         int Min = N;
 72         for(int i = head[u]; i != -1; i = edge[i].next)
 73             if(edge[i].cap-edge[i].flow&&dep[edge[i].to] < Min){
 74                   Min = dep[edge[i].to];
 75                   cur[u] = i;
 76              }
 77         if(--gap[dep[u]] == 0) break;
 78         dep[u] = Min+1;
 79         gap[dep[u]]++;
 80         if(u != s) u = edge[pre[u]^1].to;
 81     }
 82     return ans;
 83 }
 84 void clearFlow(){
 85     for(int i = 0; i < tot; i++)
 86         edge[i].flow = 0;
 87 }
 88 
 89 //ll tmp[M];
 90 //void reset(){
 91 //    for(int i = 0; i < tot; i++)
 92 //        edge[i].flow = tmp[i];
 93 //}
 94 int main(){
 95     int ca = 1;
 96     while(scanf("%d%d%lld", &n, &m, &c), n+m+c){
 97         init();
 98         int u, v, cap;
 99         for(int i = 0; i < m; i++){
100             scanf("%d%d%d", &u, &v, &cap);
101             add_edge(u, v, cap);
102         }
103         ll ans = sap(1, n, n, c);
104         printf("Case %d: ", ca++);
105         if(ans >= c) {
106             puts("possible");
107             continue ;
108         }
109 
110         for(int i = 0; i < tot; i++)
111             edge[i].cap -= edge[i].flow;
112 //        for(int i = 0; i < tot; i++)
113 //            tmp[i] = edge[i].flow;
114 
115         vector< pii > ret;
116         for(int i = 0; i < tot; i += 2){
117             if(edge[i].cap == 0) {
118                 edge[i].cap = c;
119                 clearFlow();
120                 if(ans+sap(1, n, n, c-ans) >= c)
121                     ret.push_back( pii(edge[i].from, edge[i].to) );
122                 edge[i].cap = 0;
123             }
124 //            if(edge[i].cap == edge[i].flow) {
125 //                edge[i].cap += c;
126 //                reset();
127 //                if(ans+sap(1, n, n, c-ans) >= c)
128 //                    ret.push_back( pii(edge[i].from, edge[i].to) );
129 //                edge[i].cap -= c;
130 //            }
131         }
132         if(ret.empty()){
133             puts("not possible");
134             continue ;
135         }
136         printf("possible option:");
137         sort(ret.begin(), ret.end());
138         for(int i = 0; i < ret.size(); i++)
139             printf("(%d,%d)%c", ret[i].first, ret[i].second, ",\n"[i == ret.size()-1]);
140     }
141 }
View Code

 

UVALive2957 保留流量跑最大流,输出顺序

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5 #define debug
  6 using namespace std;
  7 
  8 #define type int
  9 #define M 1000010
 10 #define N 10010
 11 #define INF 0x3f3f3f3f
 12 struct Edge{
 13     int from, to, next;
 14     type cap, flow;
 15     Edge(){}
 16     Edge(int from, int to, int next, type cap, type flow):from(from), to(to), next(next), cap(cap), flow(flow){}
 17 };
 18 int n, m, k, s, t;
 19 int u[N], v[N];
 20 struct Isap{
 21     Edge edge[M];
 22     int tot, head[N];
 23     int gap[N], d[N], pre[N], cur[N];
 24     bool vis[N];
 25     void init(){
 26         tot = 0;
 27         memset(head, -1, sizeof head);
 28     }
 29     void add_edge(int u, int v, type w, type rw = 0){
 30         edge[tot] = Edge(u, v, head[u], w, 0);
 31         head[u] = tot++;
 32         edge[tot] = Edge(v, u, head[v], rw, 0);
 33         head[v] = tot++;
 34     }
 35     void bfs(){///////////////////
 36         memset(d, -1, sizeof(d));
 37         memset(gap, 0, sizeof(gap));
 38         queue<int> Q;
 39         d[t] = 0, gap[0] = 1;
 40         Q.push(t);
 41         while(!Q.empty()){
 42             int u = Q.front(); Q.pop();
 43             for(int i = head[u]; i != -1; i = edge[i].next){
 44                 int v = edge[i].to;
 45                 if(d[v] == -1){
 46                     gap[ d[v] = d[u]+1 ]++;
 47                     Q.push(v);
 48                 }
 49             }
 50         }
 51     }
 52     type sap(int s, int t, int n, int need){
 53         memcpy(cur, head, sizeof cur);
 54         type flow = 0;
 55         bfs();
 56         int u = pre[s] = s, i;
 57         while(d[s] < n){
 58             if(u == t){
 59                 type f = INF;
 60                 for(i = s; i != t; i = edge[ cur[i] ].to)
 61                     if(f > edge[cur[i]].cap) f = edge[ cur[u = i] ].cap;
 62                 flow += f;
 63                 if(flow > need) return flow;
 64                 for(i = s; i != t; i = edge[cur[i]].to ) {
 65                     edge[cur[i]].cap -= f ;
 66                     edge[cur[i]^1].cap += f ;
 67                 }
 68             }
 69             for(i = cur[u]; ~i; i = edge[i].next)
 70                 if(edge[i].cap&&d[u] == d[edge[i].to]+1) break;
 71             if(~i){
 72                 cur[u] = i ;
 73                 pre[edge[i].to] = u;
 74                 u = edge[i].to;
 75             }else{
 76                 if(0 == --gap[d[u]]) break ;
 77                 int minv = n;
 78                 for(int i = head[u]; ~i; i = edge[i].next){
 79                     int v = edge[i].to;
 80                     if(edge[i].cap&&minv > d[v]){
 81                         minv = d[v];
 82                         cur[u] = i;
 83                     }
 84                 }
 85                 d[u] = minv + 1 ;
 86                 gap[d[u]] ++ ;
 87                 u = pre[u] ;
 88             }
 89         }
 90         return flow;
 91     }
 92 
 93     int pos[N];
 94     void print(int cnt) {
 95         for(int i = 1; i <= k; i++) pos[i] = s;
 96         printf("%d\n", cnt);
 97         for (int i = 1; i <= cnt; i++) {
 98             vector<int> u, v;
 99             memset(vis, 0, sizeof(vis));
100             for (int j = 0; j < 4 * m; j += 4) {
101                 int p = j + (i - 1) * 4 * m + n * i * 2;
102                 //正向有流量,反向没流量,也就是u-->v
103                 if(!edge[p].cap && edge[p+2].cap) {
104                     u.push_back(edge[p ^ 1].to - (i - 1) * n);
105                     v.push_back(edge[p].to - i * n);
106                 }//反向有流量,正向没流量,也就是v-->u,这样的话就排除了两边都有流量的情况,相当于两点交换了,也就是两艘飞船待在原地了
107                 else if (edge[p].cap && !edge[p + 2].cap) {
108                     u.push_back(edge[(p + 2) ^ 1].to - (i - 1) * n);
109                     v.push_back(edge[p + 2].to - i * n);
110                 }
111             }
112             printf("%d", u.size());
113             for (int p = 0; p < u.size(); p++)
114                 for (int j = 1; j <= k; j++) {
115                     if (!vis[j] && pos[j] == u[p]) {
116                         vis[j] = 1;
117                         printf(" %d %d", j, v[p]);
118                         pos[j] = v[p];
119                         break;
120                     }
121                 }
122             printf("\n");
123         }
124     }
125 };
126 Isap isap;
127 
128 int main(){
129     while(~scanf("%d%d%d%d%d", &n, &m, &k, &s, &t)){
130         for (int i = 0; i < m; i++) scanf("%d%d", u+i, v+i);
131         int cnt = 0, Maxflow = 0, sink = t;
132         isap.init();
133         while (Maxflow < k) {
134             ++cnt;
135             for (int i = 1; i <= n; i++) isap.add_edge(i+(cnt-1)*n, i+cnt*n, INF);
136             for (int i = 0; i < m; i++){
137                 isap.add_edge(u[i]+(cnt-1)*n, v[i]+cnt*n, 1);
138                 isap.add_edge(v[i]+(cnt-1)*n, u[i]+cnt*n, 1);
139             }
140             sink += n;
141             Maxflow += isap.sap(s, sink, n*cnt+n, k-Maxflow);
142         }
143         isap.print(cnt);
144     }
145     return 0;
146 }
View Code

 

Codeforces739E 概率期望/费用流

题意:小明有a个神奇宝贝球,b个超级神奇宝贝球,现在有n只神奇宝贝,两种球分别有pi, ui的概率抓到第i只神奇宝贝,一种球不能扔同一只神奇宝贝多次。问抓到的神奇宝贝个数的期望是多少?

题解:显然两种球各扔一次的抓到的概率是1-(1-pi)*(1-qi) = pi+ui-pi*ui.如何建图?某种球扔一次建边(1, -pi), 两种球各扔一次呢?从该点向汇点建两条边。第一条边是(1, 0),第二条边是(1, pi*ui), 扔一次显然会走第一条边,扔两次显然会经过第二条边。那么就有-pi-ui+pi*ui.注意精度

  1 #include <bits/stdc++.h>
  2 #define ll long long
  3 #define pii pair<int, int>
  4 #define pll pair<ll, ll>
  5 #define debug
  6 #define lson l, m, rt<<1
  7 #define rson m+1, r, rt<<1|1
  8 #define type double
  9 using namespace std;
 10 const int maxm = 2e5+5, maxn = 2100;
 11 #define INF 1e20
 12 #define eps 1e-8
 13 int s, t, N;
 14 struct Edge{
 15     int u, v, next;
 16     type cap, flow, cost;
 17     Edge(){}
 18     Edge(int u, int v, int next, type cap, type flow, type cost):u(u), v(v), next(next), cap(cap), flow(flow), cost(cost){}
 19 };
 20 
 21 Edge edge[maxm];
 22 int cnt, head[maxn], pre[maxn];
 23 type dis[maxn];
 24 bool vis[maxn];
 25 
 26 void init () {
 27     memset (head, -1, sizeof head);
 28     cnt = 0;
 29 }
 30 void add_edge(int u, int v, type cap, type cost) {
 31     edge[cnt] = Edge(u, v, head[u], cap, 0, cost);
 32     head[u] = cnt++;
 33     edge[cnt] = Edge(v, u, head[v], 0, 0, -cost);
 34     head[v] = cnt++;
 35 }
 36 bool spfa(int s, int t) {
 37     queue<int> Q;
 38     for(int i = 0; i < N; i++)
 39         dis[i] = INF, vis[i] = 0, pre[i] = -1;
 40     dis[s] = 0, vis[s] = 1;
 41     Q.push(s);
 42     while(!Q.empty()){
 43         int u = Q.front(); Q.pop();
 44         vis[u] = 0;
 45         for(int i = head[u]; i != -1; i = edge[i].next){
 46             int v = edge[i].v;
 47             if(edge[i].cap > edge[i].flow+eps&&dis[v] > dis[u]+edge[i].cost+eps){//注意精度
 48                 dis[v] = dis[u]+edge[i].cost;
 49                 pre[v] = i;
 50                 if (!vis[v]){
 51                     vis[v] = 1;
 52                     Q.push(v);
 53                 }
 54             }
 55         }
 56     }
 57     return pre[t] != -1;
 58 }
 59 type MCMF(int s, int t, type &cost){
 60     type flow = 0;
 61     cost = 0;
 62     while(spfa(s, t)){
 63         type Min = INF;
 64         for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){
 65             if (Min > edge[i].cap-edge[i].flow)
 66                     Min = edge[i].cap-edge[i].flow;
 67         }
 68         for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){
 69             edge[i].flow += Min;
 70             edge[i^1].flow -= Min;
 71             cost += edge[i].cost*Min;
 72         }
 73         flow += Min;
 74     }
 75     return flow;
 76 }
 77 
 78 double p[2333], u[2333];
 79 int main(){
 80     int n, a, b;
 81     scanf("%d%d%d", &n, &a, &b);
 82     for(int i = 1; i <= n; i++) scanf("%lf", p+i);
 83     for(int i = 1; i <= n; i++) scanf("%lf", u+i);
 84     init();
 85     N = n+4;
 86     add_edge(0, n+1, a, 0);
 87     add_edge(0, n+2, b, 0);
 88     for(int i = 1; i <= n; i++)
 89         add_edge(n+1, i, 1, -p[i]);
 90     for(int i = 1; i <= n; i++)
 91         add_edge(n+2, i, 1, -u[i]);
 92     for(int i = 1; i <= n; i++){
 93         add_edge(i, n+3, 1, 0);
 94         add_edge(i, n+3, 1, p[i]*u[i]);
 95     }
 96     double ans;
 97     MCMF(0, n+3, ans);
 98     printf("%.5f\n", -ans);
 99     return 0;
100 }
View Code

 

hdu5988 2016青岛费用流

  1 //自从某次交上去后跑了951MS,之后再交就tle了
  2 #include <bits/stdc++.h>
  3 #define ll long long
  4 #define pii pair<int, int>
  5 #define pll pair<ll, ll>
  6 #define debug
  7 #define lson l, m, rt<<1
  8 #define rson m+1, r, rt<<1|1
  9 #define type double
 10 using namespace std;
 11 const int maxm = 2e5+5, maxn = 2100;
 12 #define INF 2e9
 13 #define eps 1e-6
 14 int s, t, N;
 15 struct Edge{
 16     int u, v, next, cap, flow;
 17     type cost;
 18     Edge(){}
 19     Edge(int u, int v, int next, int cap, int flow, type cost):u(u), v(v), next(next), cap(cap), flow(flow), cost(cost){}
 20 };
 21 
 22 Edge edge[maxm];
 23 int cnt, head[maxn], pre[maxn];
 24 type dis[maxn];
 25 bool vis[maxn];
 26 
 27 void init () {
 28     memset (head, -1, sizeof head);
 29     cnt = 0;
 30 }
 31 
 32 void add_edge(int u, int v, int cap, type cost) {
 33     edge[cnt] = Edge(u, v, head[u], cap, 0, cost);
 34     head[u] = cnt++;
 35     edge[cnt] = Edge(v, u, head[v], 0, 0, -cost);
 36     head[v] = cnt++;
 37 }
 38 int Q[10*maxn];
 39 bool spfa(int s, int t) {
 40     //queue<int> Q;
 41     int front = 0, quer = 0;
 42     for(int i = 0; i < N; i++)
 43         dis[i] = INF, vis[i] = 0, pre[i] = -1;
 44     dis[s] = 0, vis[s] = 1;
 45     Q[quer++] = s;
 46     //Q.push(s);
 47     //while(!Q.empty()){
 48     while(front != quer){
 49         int u = Q[front++];
 50         //int u = Q.front(); Q.pop();
 51         vis[u] = 0;
 52         for(int i = head[u]; i != -1; i = edge[i].next){
 53             int v = edge[i].v;
 54             if(edge[i].cap > edge[i].flow+eps&&dis[v] > dis[u]+edge[i].cost+eps){//注意精度
 55                 dis[v] = dis[u]+edge[i].cost;
 56                 pre[v] = i;
 57                 if (!vis[v]){
 58                     vis[v] = 1;
 59                     Q[quer++] = v;
 60                     //Q.push(v);
 61                 }
 62             }
 63         }
 64     }
 65     return pre[t] != -1;
 66 }
 67 int MCMF(int s, int t, type &cost){
 68     int flow = 0;
 69     cost = 0;
 70     while(spfa(s, t)){
 71         int Min = INF;
 72         for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){
 73             if (Min > edge[i].cap-edge[i].flow)
 74                     Min = edge[i].cap-edge[i].flow;
 75         }
 76         for(int i = pre[t]; i != -1; i = pre[edge[i^1].v]){
 77             edge[i].flow += Min;
 78             edge[i^1].flow -= Min;
 79             cost += edge[i].cost*Min;
 80         }
 81         flow += Min;
 82     }
 83     return flow;
 84 }
 85 
 86 int main(){
 87     int n, m, t; scanf("%d", &t);
 88     while(t--){
 89         init();
 90         scanf("%d%d", &n, &m);
 91         N = n+2;
 92         int s, b;
 93         for(int i = 1; i <= n; i++) {
 94             scanf("%d%d", &s, &b);
 95             int tmp = min(s, b);
 96             s -= tmp, b -= tmp;
 97             if(s) add_edge(0, i, s, 0);
 98             if(b) add_edge(i, n+1, b, 0);
 99             //add_edge(i, n+i, INF, 0);
100         }
101         int u, v, c; double p;
102         for(int i = 0; i < m; i++){
103             scanf("%d%d%d%lf", &u, &v, &c, &p);
104             if(c){
105                 add_edge(u, v, 1, 0);
106                 if(c > 1)
107                     add_edge(u, v, c-1, -log(1.0-p) );
108             }
109         }
110 
111         double ans;
112         MCMF(0, n+1, ans);
113         ans = 1-exp(-ans);
114         printf("%.2f\n", ans);
115     }
116     return 0;
117 }
View Code

 

posted @ 2016-12-06 12:21  我在地狱  阅读(409)  评论(0编辑  收藏  举报