zoukankan      html  css  js  c++  java
  • hdu 1853 (费用流 拆点)

    // 给定一个有向图,必须用若干个环来覆盖整个图,要求这些覆盖的环的权值最小。 

    思路:原图每个点 u 拆为 u 和 u' ,从源点引容量为 1 费用为 0 的边到 u ,从 u' 引相同性质的边到汇点,若原图中存在 (u, v) ,则从 u 引容量为 1 费用为 c(u, v) 的边到 v' 。

    其实这里的源模拟的是出度,汇模拟的是入度,因为环中每个点的出度等于入度等于 1 ,那么如果最大流不等于顶点数 n ,则无解;否则,答案就是最小费用。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 
      6 using namespace std;
      7 
      8 const int maxn = 2e2 + 5;
      9 const int maxm = 2e4 + 5;
     10 const int inf = 0x3f3f3f3f;
     11 
     12 struct MCMF
     13 {
     14     struct Edge
     15     {
     16         int v, c, w, next;
     17     }p[maxm << 1];
     18     int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n;
     19     bool vis[maxn];
     20     void init(int nt)
     21     {
     22         e = 0, n = nt;
     23         memset(head, -1, sizeof(head[0]) * (n + 2) );
     24     }
     25     void addEdge(int u, int v, int c, int w)
     26     {
     27         p[e].v = v, p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++;
     28         swap(u, v);
     29         p[e].v = v, p[e].c = 0; p[e].w = -w; p[e].next = head[u]; head[u] = e++;
     30     }
     31     bool spfa(int S, int T)
     32     {
     33         queue <int> q;
     34         for (int i = 0; i <= n; ++i)
     35             vis[i] = cnt[i] = 0, pre[i] = -1, dis[i] = inf;
     36         vis[S] = 1, dis[S] = 0;
     37         q.push(S);
     38         while (!q.empty())
     39         {
     40             int u = q.front(); q.pop();
     41             vis[u] = 0;
     42             for (int i = head[u]; i + 1; i = p[i].next)
     43             {
     44                 int v = p[i].v;
     45                 if (p[i].c && dis[v] > dis[u] + p[i].w)
     46                 {
     47                     dis[v] = dis[u] + p[i].w;
     48                     pre[v] = i;
     49                     if (!vis[v])
     50                     {
     51                         q.push(v);
     52                         vis[v] = 1;
     53                         if (++cnt[v] > n) return 0;
     54                     }
     55                 }
     56             }
     57         }
     58         return dis[T] != inf;
     59     }
     60     int mcmf(int S, int T)
     61     {
     62         sumFlow = 0;
     63         int minFlow = 0, minCost = 0;
     64         while (spfa(S, T))
     65         {
     66             minFlow = inf + 1;
     67             for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ])
     68                 minFlow = min(minFlow, p[i].c);
     69             sumFlow += minFlow;
     70             for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ])
     71             {
     72                 p[i].c -= minFlow;
     73                 p[i ^ 1].c += minFlow;
     74             }
     75             minCost += dis[T] * minFlow;
     76         }
     77         return minCost;
     78     }
     79     void build(int nt, int mt)
     80     {
     81         init((nt << 1) + 1);
     82         int u, v, c;
     83         for (int i = 1; i <= nt; ++i)
     84         {
     85             addEdge(0, i, 1, 0);
     86             addEdge(i + nt, n, 1, 0);
     87         }
     88         while (mt--)
     89         {
     90             scanf("%d%d%d", &u, &v, &c);
     91             addEdge(u, v + nt, 1, c);
     92         }
     93     }
     94     void solve(int nt)
     95     {
     96         int ans = mcmf(0, n);
     97         if ( sumFlow != nt)
     98             printf("-1
    ");
     99         else
    100             printf("%d
    ", ans);
    101     }
    102 }my;
    103 
    104 int main()
    105 {
    106     int n, m;
    107     while (~scanf("%d%d", &n, &m))
    108     {
    109         my.build(n, m);
    110         my.solve(n);
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/Missa/p/3265691.html
Copyright © 2011-2022 走看看