hdu 3667 (拆边 mcmf)

注意题目中 边的容量 <= 5.可以把费用权值 a *f ^2化归成 a * f2, 即第一条边费用为 1 * a, 第二条 为 (4 - 1) * a, 第三条为 (9  - 4) * a。。。。。。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 
  6 using namespace std;
  7 
  8 const int maxn = 110;
  9 const int maxm = 25000;
 10 const int inf = 0x3f3f3f3f;
 11 const int ww[5] = {1, 3, 5, 7, 9};
 12 
 13 struct MCMF
 14 {
 15     struct Edge
 16     {
 17         int v, c, w, next;
 18     }p[maxm << 1];
 19     int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n;
 20     bool vis[maxn];
 21     void init(int nt)
 22     {
 23         e = 0; n = nt;
 24         memset(head, -1, sizeof(head[0]) * (n + 2));
 25     }
 26     void addEdge(int u, int v, int c, int w)
 27     {
 28         p[e].v = v; p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++;
 29         swap(u, v);
 30         p[e].v = v; p[e].c = 0; p[e].w =-w; p[e].next = head[u]; head[u] = e++;
 31     }
 32     bool spfa(int S, int T)
 33     {
 34         queue <int> q;
 35         for (int i = 0; i <= n; ++i)
 36             vis[i] = cnt[i] = 0, pre[i] = -1, dis[i] = inf;
 37         vis[S] = 1; dis[S] = 0;
 38         q.push(S);
 39         while (!q.empty())
 40         {
 41             int u = q.front(); q.pop();
 42             vis[u] = 0;
 43             for (int i = head[u]; i + 1; i = p[i].next)
 44             {
 45                 int v = p[i].v;
 46                 if (p[i].c && dis[v] > dis[u] + p[i].w)
 47                 {
 48                     dis[v] = dis[u] + p[i].w;
 49                     pre[v] = i;
 50                     if (!vis[v])
 51                     {
 52                         q.push(v);
 53                         vis[v] = 1;
 54                         if (++cnt[v] > n) return 0;
 55                     }
 56                 }
 57             }
 58         }
 59         return dis[T] != inf;
 60     }
 61     int mcmf(int S, int T)
 62     {
 63         sumFlow = 0;
 64         int minFlow = 0, minCost = 0;
 65         while (spfa(S, T))
 66         {
 67             minFlow = inf + 1;
 68             for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ])
 69                 minFlow = min(minFlow, p[i].c);
 70             sumFlow += minFlow;
 71             for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ])
 72                 p[i].c -= minFlow, p[i ^ 1].c += minFlow;
 73             minCost += dis[T] * minFlow;
 74         }
 75         return minCost;
 76     }
 77     void build(int nt, int mt, int kt)
 78     {
 79         init(nt);
 80         addEdge(0, 1, kt, 0);
 81         int u, v, c, w;
 82         for (int i = 0; i < mt; ++i)
 83         {
 84             scanf("%d%d%d%d", &u, &v, &w, &c);
 85             for (int j = 0; j < c; ++j)
 86                 addEdge(u, v, 1, w * ww[j]);
 87         }
 88     }
 89     void solve(int nt, int mt, int kt)
 90     {
 91         build(nt, mt, kt);
 92         int ans = mcmf(0, n);
 93     //    cout <<"sumFlow = "  << sumFlow << " cost = " << ans << endl;
 94         if (sumFlow != kt)
 95             printf("-1\n");
 96         else
 97             printf("%d\n", ans);
 98     }
 99 }my;
100 
101 int main()
102 {
103     int n, m, k;
104     while (~scanf("%d%d%d", &n, &m, &k))
105         my.solve(n, m, k);
106     return 0;
107 }

 

posted @ 2013-08-17 09:24  Missa  阅读(287)  评论(0编辑  收藏  举报