zoukankan      html  css  js  c++  java
  • hdu Kaka's Matrix Travels(最小费用最大流)

    把题意写一下:  给你一个n*n的矩阵,每个格子都有一个非负整数,从左上角走到右下角,收集走过的数字,累加,但是只能向右或者向下走,走过之后数字就变为0,让你求从左上角到右下角,走k次之后,所得的最大值是多少。

    典型的最小费用最大流入门题,只需在建图时,把源点到1的cap设成k,对走完一次变成0的处理时,只需拆点,拆成两条边,一条容量为1,权值为点权,另一条是跳板,容量为inf,费用为0,即可

    ****************************************************************************************************************

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #define M 200001
      4 #define maxx 2000
      5 #define Max(a, b) a > b ? a : b
      6 #define Min(a, b) a < b ? a : b
      7 #define inf (1 << 29)
      8 struct T
      9 {
     10     int u, v, val, next, cost;
     11 } e[M];
     12 int th;
     13 int visit[M], pre[M], dis[M], que[M], g[M], pos[M], map[100][100];
     14 void add(int u, int v, int val, int cost)
     15 {
     16     e[th].u = u, e[th].v = v, e[th].val = val, e[th].cost = cost;
     17     e[th].next = g[u], g[u] = th++;
     18     e[th].u = v, e[th].v = u, e[th].val = 0, e[th].cost = -cost;
     19     e[th].next = g[v], g[v] = th++;
     20 }
     21 int spfa(int s, int t, int n)
     22 {
     23     int i, u, v, k;
     24     for (i = 0; i <= n; i++)
     25     {
     26         pre[i] = -1, visit[i] = 0;
     27     }
     28     int head, tail;
     29     head = tail = 0;
     30     for (i = 0; i <= n; i++) dis[i] = -1;//求最小费用时这里得改成正无穷
     31     que[tail++] = s, pre[s] = s, dis[s] = 0, visit[s] = 1;
     32     while (head != tail)
     33     {
     34         int u = que[head++];
     35         visit[u] = 0;
     36         for (k = g[u]; k != -1; k = e[k].next)
     37         {
     38             v = e[k].v;
     39             if (e[k].val > 0 && dis[u] + e[k].cost > dis[v])//最大费用,求最小费用时这里的改符号
     40             {
     41                 dis[v] = dis[u] + e[k].cost;
     42                 pre[v] = u;
     43                 pos[v] = k;
     44                 if (!visit[v])
     45                 {
     46                     visit[v] = 1;
     47                     que[tail++] = v;
     48                 }
     49             }
     50         }
     51     }
     52     if (pre[t] != -1 && dis[t] > -1)//求最小费用时这里改成dit[t] < 正无穷
     53     {
     54         return 1;
     55     }
     56     return 0;
     57 }
     58 int MinCostFlow(int s, int t, int n)
     59 {
     60     if (s == t)
     61     {
     62         //这里具体情况具体分析,如果有附加s跟t就不用,如果用数据中的点作为s跟t就得考虑
     63         //直接返回某个值。否则spfa里的队列会死循环。
     64     }
     65     int flow = 0, cost = 0;
     66     while (spfa(s, t, n))
     67     {
     68         int u, min = inf;
     69         for (u = t; u != s; u = pre[u])
     70         {
     71             min = Min(min, e[pos[u]].val);
     72         }
     73         flow += min;
     74         cost += dis[t] * min;
     75         for (u = t; u != s; u = pre[u])
     76         {
     77             e[pos[u]].val -= min;
     78             e[pos[u]^1].val += min;
     79         }
     80     }
     81     return cost;
     82 }
     83 int main()
     84 {
     85     int n, m, i, j, k, s, t, u, v, cost, ans, x, num, tt;
     86     while (scanf("%d%d", &n, &m) - EOF)
     87     {
     88         for (i = 0, th = 0; i < n * n * 3 + 2; i++)
     89         {
     90             g[i] = -1;
     91         }
     92         for (i = 0; i < n; i++)
     93         {
     94             for (j = 0; j < n; j++)
     95             {
     96                 scanf("%d", &map[i][j]);
     97             }
     98         }
     99         num = n * n;
    100         for (i = 0; i < n; i++)
    101         {
    102             for (j = 0; j < n; j++)
    103             {
    104                 x = i * n + j;
    105                 add(x, x + num, 1, map[i][j]);
    106                 add(x, x + num, inf, 0);
    107                 if (i + 1 < n)
    108                 {
    109                     add(x + num, x + n, inf, 0);
    110                 }
    111                 if (j + 1 < n)
    112                 {
    113                     add(x + num, x + 1, inf, 0);
    114                 }
    115             }
    116         }
    117         s = 2 * n * n, t = s + 1, n = t + 1;
    118         add(s, 0, m, 0);
    119         add(s - 1, t, m, 0);
    120         ans = MinCostFlow(s, t, t + 1);
    121         printf("%d
    ", ans);
    122     }
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    有趣的开源家族合照,看看你认识几个?
    fieldset 使用小案例
    java XMPPserver openfire VS tigase
    tomcat 7 jmx配置访问
    JAVA静态域及容器的内存占用探究
    checkStyle字符集不支持解决--Got an exception
    遇到一个很无语的Andorid问题! button 里 android:textColor 属性 设置一个选择器报错!
    android 关于为什么在onCreate里调用view.getChildAt(1).getLeft() 没有值!
    关于Android studio 怎么使用代码混淆的问题!
    sdk manager.exe 闪退 解决办法!
  • 原文地址:https://www.cnblogs.com/sdau--codeants/p/3534734.html
Copyright © 2011-2022 走看看