zoukankan      html  css  js  c++  java
  • 单纯性与网络流

    单纯性模板:

    需要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
    ", 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
    ", 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
    ", 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, ",
    "[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
    ", 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("
    ");
    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
    ", -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
    ", ans);
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    归并排序,树状数组 两种方法求逆序对
    volley源代码解析(六)--HurlStack与HttpClientStack之争
    what&#39;s new in vc2015
    [ajax 学习笔记] ajax初试
    安卓项目开发实战(1)--首页顶部菜单BAR实现
    eclipse下Tomcat7.0启动奔溃问题
    伸缩--也可用于tabs
    怎样提高团队管理能力8
    mysql查询今天,昨天,近7天,近30天,本月,上一月数据
    SDSoC使用体验
  • 原文地址:https://www.cnblogs.com/dirge/p/6137106.html
Copyright © 2011-2022 走看看