zoukankan      html  css  js  c++  java
  • HDU 3667 费用流 拆边 Transportation

    题意:

    有N个城市,M条有向道路,要从1号城市运送K个货物到N号城市。

    每条有向道路<u, v>运送费用和运送量的平方成正比,系数为ai

    而且每条路最多运送Ci个货物,求最小费用。

    分析:

    拆边,每条边拆成费用为a, 3a, 5a的边,这样就能保证每条边的费用和流量的平方成正比。

    因为最多运送K个货物,所以增加一个源点和城市1连一条容量为K费用为0的边。

    跑一边最小费用最大流,如果满流才有解。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <vector>
      7 using namespace std;
      8 
      9 const int maxn = 100 + 10;
     10 const int INF = 0x3f3f3f3f;
     11 
     12 struct Edge
     13 {
     14     int from, to, cap, flow, cost;
     15     Edge(int u, int v, int cap, int flow, int cost):from(u), to(v), cap(cap), flow(flow), cost(cost) {}
     16 };
     17 
     18 int n, s, t, m, k;
     19 vector<Edge> edges;
     20 vector<int> G[maxn];
     21 
     22 void init(int n)
     23 {
     24     for(int i = 0; i < n; i++) G[i].clear();
     25     edges.clear();
     26 }
     27 
     28 void AddEdge(int u, int v, int cap, int cost)
     29 {
     30     edges.push_back(Edge(u, v, cap, 0, cost));
     31     edges.push_back(Edge(v, u, 0, 0, -cost));
     32     int m = edges.size();
     33     G[u].push_back(m - 2);
     34     G[v].push_back(m - 1);
     35 }
     36 
     37 bool inq[maxn];
     38 int p[maxn], d[maxn], a[maxn];
     39 
     40 bool SPFA()
     41 {
     42     memset(d, 0x3f, sizeof(d));
     43     d[s] = 0;
     44     queue<int> Q;
     45     Q.push(s);
     46     memset(inq, false, sizeof(inq));
     47     inq[s] = true;
     48     memset(p, -1, sizeof(p));
     49     a[s] = INF;
     50 
     51     while(!Q.empty())
     52     {
     53         int u = Q.front(); Q.pop(); inq[u] = false;
     54         for(int i = 0; i < G[u].size(); i++)
     55         {
     56             Edge& e = edges[G[u][i]];
     57             int v = e.to;
     58             if(e.cap > e.flow && d[u] + e.cost < d[v])
     59             {
     60                 d[v] = d[u] + e.cost;
     61                 p[v] = G[u][i];
     62                 a[v] = min(a[u], e.cap - e.flow);
     63                 if(!inq[v]) { inq[v] = true; Q.push(v); }
     64             }
     65         }
     66     }
     67 
     68     return d[t] < INF;
     69 }
     70 
     71 int Maxf;
     72 
     73 int Mincost()
     74 {
     75     int cost = 0;
     76     Maxf = 0;
     77     while(SPFA())
     78     {
     79         Maxf += a[t];
     80         cost += a[t] * d[t];
     81         int u = t;
     82         while(u != s)
     83         {
     84             edges[p[u]].flow += a[t];
     85             edges[p[u]^1].flow -= a[t];
     86             u = edges[p[u]].from;
     87         }
     88     }
     89     return cost;
     90 }
     91 
     92 int main()
     93 {
     94     while(scanf("%d%d%d", &n, &m, &k) == 3)
     95     {
     96         init(n + 1);
     97 
     98         s = 0, t = n;
     99         AddEdge(s, 1, k, 0);
    100 
    101         while(m--)
    102         {
    103             int u, v, a, C;
    104             scanf("%d%d%d%d", &u, &v, &a, &C);
    105             for(int i = 0; i < C; i++)
    106                 AddEdge(u, v, 1, a * (i * 2 + 1));
    107         }
    108 
    109         int cost = Mincost();
    110         if(Maxf < k) puts("-1");
    111         else printf("%d
    ", cost);
    112     }
    113 
    114     return 0;
    115 }
    代码君
  • 相关阅读:
    Vim深入研究
    信息安全系统设计基础第十三周学习总结——20135308
    信息安全系统设计基础实验五:通讯协议设计
    信息安全系统设计基础第十二周学习总结 ——20135308
    信息安全系统设计基础实验四:外设驱动程序设计
    信息安全系统设计基础实验三:实时系统的移植
    GDB深入研究——20135308芦畅
    信息安全系统设计基础第十一周学习总结——20135308
    第九次ScrumMeeting博客
    第八次ScrumMeeting博客
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4797324.html
Copyright © 2011-2022 走看看