zoukankan      html  css  js  c++  java
  • POJ 3422 【最大费用】.cpp

    题意:

    给出一个每一格带值的矩阵

    每一次只可以从左上角走到右下角

    问走过k次后最多能得到多少值

    P.S 走过的格子值会变成0

    输入:

      给出一个n 和 k

      给出n*n 矩阵

     

    思路:

      因为求的是最大值

      所以应该求最长距离..把最小路径改成求最大路径

      <相应改变的就是松弛操作 和 dis的初始状态>

      

      为了保证每个点只取一次值 并且 可以经过多次

      就进行拆点 然后对应点之间加两条边 ①. 容量为1 费用为该点的值 ②. 容量为INF 费用为0

      ①边保证了该点走过后变为0值 ②边保证该点可以经过多次

     

      还有超级源点跟每个点之间连边 容量为k 费用为0

      超级汇点和每个拆点之间连边 容量为k 费用为0

     

    Tips:

      加边的时候记得判断边界情况..

      还有因为拆点了 和 加了超级源点和汇点  边数就要相应增多..

      循环队列也要开大点..  

     

    Code:

    View Code
      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 #define clr(x) memset(x, 0, sizeof(x))
      6 const int INF = 0x1f1f1f1f;
      7 const int MAXN = 6000;
      8 const int MAXM = 100010;
      9 struct Edge
     10 {
     11     int from;
     12     int to;
     13     int next;
     14     int c;
     15     int f;
     16 }edge[MAXM];
     17 int head[MAXN];
     18 int tot;
     19 int n, k;
     20 int dis[MAXN], pre[MAXN];
     21 bool flag[MAXN];
     22 
     23 void add(int s, int u, int c, int f)
     24 {
     25     edge[tot].from = s;
     26     edge[tot].to = u;
     27     edge[tot].next = head[s];
     28     edge[tot].f = f;
     29     edge[tot].c = c;
     30     head[s] = tot++;
     31 
     32     edge[tot].from = u;
     33     edge[tot].to = s;
     34     edge[tot].f = 0;
     35     edge[tot].c = -c;
     36     edge[tot].next = head[u];
     37     head[u] = tot++;
     38 }
     39 
     40 int que[MAXN*100];
     41 bool spfa(int s, int e)
     42 {
     43     int qout, qin;
     44     clr(flag);
     45     memset(pre, 0xff, sizeof(pre));
     46     memset(dis, 0xff, sizeof(dis));
     47     qin = qout = 0;
     48     que[qin++] = s;
     49     dis[s] = 0;
     50     flag[s] = true;
     51     while(qin != qout) {
     52         int tmpe = que[qout++];
     53         flag[tmpe] = false;
     54         for(int i = head[tmpe]; i != -1; i = edge[i].next) {
     55             int ne = edge[i].to;
     56             if(edge[i].f && dis[ne]-dis[tmpe] < edge[i].c) {
     57                 dis[ne] = dis[tmpe]+edge[i].c;
     58                 pre[ne] = i;
     59                 if(!flag[ne]) {
     60                     flag[ne] = true;
     61                     que[qin++] = ne;
     62                 }
     63             }
     64         }
     65     }
     66 
     67     if(dis[e] == -1)
     68         return false;
     69     else return true;
     70 }
     71 
     72 int min_c_f(int s, int e)
     73 {
     74     int u, mn;
     75     int ans_f = 0, ans_c = 0;
     76     while(spfa(s, e))
     77     {
     78         u = pre[e];
     79         mn = INF;
     80         while(u != -1) {
     81             mn = min(edge[u].f, mn);
     82             u = pre[edge[u].from];
     83         }
     84         u = pre[e];
     85         while(u != -1) {
     86             edge[u].f -= mn;
     87             edge[u^1].f += mn;
     88             u = pre[edge[u].from];
     89         }
     90         ans_c += dis[e]*mn;
     91         ans_f += mn;
     92     }
     93     return ans_c;
     94 }
     95 
     96 int main()
     97 {
     98     int i, j;
     99     int w, t;
    100     while(scanf("%d %d", &n, &k) != EOF)
    101     {
    102         tot = 0, t = n*n;
    103         memset(head, 0xff, sizeof(head));
    104         clr(flag), clr(dis), clr(pre);
    105 
    106         for(i = 1; i <= t; ++i) {
    107             scanf("%d", &w);
    108             add(i, i+t, w, 1);
    109             add(i, i+t, 0, INF);
    110             if(i%n != 0)
    111                 add(i+t, i+1, 0, INF);
    112             if(i <= t-n)
    113                 add(i+t, i+n, 0, INF);
    114         }
    115 
    116         add(0, 1, 0, k);
    117         add(2*t, 2*t+1, 0, k);
    118         int ans = min_c_f(0, 2*t+1);
    119         printf("%d\n", ans);
    120     }
    121     return 0;
    122 }

     

    题目链接:http://poj.org/problem?id=3422

  • 相关阅读:
    USB无线网卡导致耳机电流声很大
    知乎广告太多怎么办?
    网络机顶盒固件提取、编辑和打包
    GOOGLE机器学习速成班
    windows xp版本的chrome浏览器去哪里下载呢?
    [转载]HTTP无状态是什么意思?
    [转载]HTTP的无状态是什么意思?
    安卓手机网页打开淘宝总是弹出应用市场
    PLSQL Developer 客户端工具的安装
    VMware虚拟网卡设置问题
  • 原文地址:https://www.cnblogs.com/Griselda/p/2710536.html
Copyright © 2011-2022 走看看