zoukankan      html  css  js  c++  java
  • hoj 2543 (费用流 拆边)

    http://acm.hit.edu.cn/hoj/problem/view?id=2543

    1.将原图中的每条边(u, v)拆成两条:(u, v, Ci, 0), (u, v, ∞, Ei)

    2.购买的每个石头的费用P加一条 (S, 1, inf, P)的边。

    3.总的能够花费的费用C可以在我们求最小费用路的时候判断。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 #include <algorithm>
      6 #include <cmath>
      7 
      8 using namespace std;
      9 typedef long long LL;
     10 const int maxn = 1e3 + 5;
     11 const int maxm = 1e5+ 5;
     12 const int inf = 0x3f3f3f3f;
     13 
     14 struct MCMF
     15 {
     16     struct Edge
     17     {
     18         int v, c, w, next;
     19     }p[maxm << 1];
     20     int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n;
     21     bool vis[maxn];
     22     void init(int nt)
     23     {
     24         e = 0, n = nt;
     25         memset(head, -1, sizeof(head[0]) * (n + 2) );
     26     }
     27     void addEdge(int u, int v, int c, int w)
     28     {
     29         p[e].v = v; p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++;
     30         swap(u, v);
     31         p[e].v = v; p[e].c = 0; p[e].w = -w; p[e].next = head[u]; head[u] = e++;
     32     }
     33     bool spfa(int S, int T)
     34     {
     35         queue <int> q;
     36         for (int i = 0; i <= n; ++i)
     37             vis[i] = cnt[i] = 0, pre[i] = -1, dis[i] = inf;
     38         vis[S] = 1, dis[S] = 0;
     39         q.push(S);
     40         while (!q.empty())
     41         {
     42             int u = q.front(); q.pop();
     43             vis[u] = 0;
     44             for (int i = head[u]; i + 1; i = p[i].next)
     45             {
     46                 int v = p[i].v;
     47                 if (p[i].c && dis[v] > dis[u] + p[i]. w)
     48                 {
     49                     dis[v] = dis[u] + p[i].w;
     50                     pre[v] = i;
     51                     if (!vis[v])
     52                     {
     53                         q.push(v);
     54                         vis[v] = 1;
     55                         if (++cnt[v] > n) return 0;
     56                     }
     57                 }
     58             }
     59         }
     60         return dis[T] != inf;
     61     }
     62     void mcmf(int S, int T, int ct)
     63     {
     64         sumFlow = 0;
     65         LL minFlow = 0, minCost = 0;
     66         while (spfa(S, T))
     67         {
     68             minFlow = inf + 1;
     69             for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ])
     70                 minFlow = min(minFlow,(LL)p[i].c);
     71             sumFlow += minFlow;
     72             for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ])
     73             {
     74                 p[i].c -= minFlow;
     75                 p[i ^ 1].c == minFlow;
     76             }
     77             minCost += dis[T] * minFlow;
     78             if (minCost > ct)
     79             {
     80                 sumFlow -= ceil((minCost - ct) * 1.0 / dis[T]);
     81                 break;
     82             }
     83         }
     84     }
     85     void build(int nt, int mt, int ct, int pt)
     86     {
     87         init(nt);
     88         int u, v, c, w;
     89         addEdge(0, 1, inf, pt);
     90         while (mt--)
     91         {
     92             scanf("%d%d%d%d", &u, &v, &c, &w);
     93             u++, v++;
     94             addEdge(u, v, c, 0); addEdge(u, v, inf, w);
     95             swap(u, v);
     96             addEdge(u, v, c, 0); addEdge(u, v, inf, w);
     97         }
     98     }
     99     void solve(int nt, int mt, int ct, int pt)
    100     {
    101         build(nt, mt, ct, pt);
    102         mcmf(0, 2, ct);
    103         printf("%d
    ", sumFlow);
    104     }
    105 }my;
    106 int main()
    107 {
    108     int tcase, n, m, c, p;
    109     scanf("%d", &tcase);
    110     while (tcase--)
    111     {
    112         scanf("%d%d%d%d",&n, &m, &c, &p);
    113         my.solve(n, m, c, p);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    Python运算符及逻辑运算
    Python编码、流程控制、格式化输出
    Docker私有仓库Harbor部署与使用
    react
    理事会
    关于elementui form表单过长,看不到未填项
    js
    vue 父子传值
    养生
    html知识点
  • 原文地址:https://www.cnblogs.com/Missa/p/3265837.html
Copyright © 2011-2022 走看看