zoukankan      html  css  js  c++  java
  • Vijos1653 疯狂的方格取数

    题目链接:https://vijos.org/p/1653

    描述

    在一个宽M,长N的矩阵中,请你编一个程序,n次从矩阵的左上角走到矩阵的右下角,每到一处,就取走该处的数字,请你选择一
    种走法使取得的数字的和最大,并输出其最大值。其中:3<=M<=20 M<=N<=100 1<=n<=10

    K路方格取数的费用流做法

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <queue>
     6 #define rep(i,l,r) for(int i=l; i<=r; i++)
     7 #define clr(x,y) memset(x,y,sizeof(x))
     8 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
     9 using namespace std;
    10 const int INF = 0x3f3f3f3f;
    11 const int maxn = 110;
    12 const int maxm = 30;
    13 inline int read(){
    14     int ans = 0, f = 1;
    15     char c = getchar();
    16     for(; !isdigit(c); c = getchar())
    17     if (c == '-') f = -1;
    18     for(; isdigit(c); c = getchar())
    19     ans = ans * 10 + c - '0';
    20     return ans * f;
    21 }
    22 struct Edge{
    23     Edge *pre,*rev; int to,cap,cost;
    24 }edge[maxn*maxm*4],*last[maxn*maxm*2],*pre[maxn*maxm*2],*pt;
    25 int n,m,k,N,S,T,pos[maxn][maxm][2],w[maxn][maxm],d[maxn*maxm*2];
    26 bool isin[maxn*maxm*2];
    27 queue <int> q;
    28 inline void add(int x,int y,int z,int w){
    29     pt->pre = last[x]; pt->to = y; pt->cap = z; pt->cost = w; last[x] = pt++;
    30     pt->pre = last[y]; pt->to = x; pt->cap = 0; pt->cost = -w; last[y] = pt++;
    31     last[x]->rev = last[y]; last[y]->rev = last[x];
    32 }
    33 bool spfa(){
    34     clr(isin,0); isin[S] = 1; q.push(S);
    35     clr(d,INF); d[S] = 0;
    36     while (!q.empty()){
    37         int now = q.front(); q.pop(); isin[now] = 0;
    38         travel(now){
    39             if (p->cap && d[p->to] > d[now] + p->cost){
    40                 d[p->to] = d[now] + p->cost;
    41                 pre[p->to] = p;
    42                 if (!isin[p->to]){
    43                     isin[p->to] = 1; q.push(p->to);
    44                 }
    45             }
    46         }
    47     }
    48     return d[T] != INF;
    49 }
    50 int mincost(){
    51     int ret = 0, x = INF;
    52     while (spfa()){
    53         for(Edge *p = pre[T]; p; p = pre[p->rev->to]) x = min(x,p->cap);
    54         for(Edge *p = pre[T]; p; p = pre[p->rev->to]){
    55             ret += x * p->cost; p->cap -= x; p->rev->cap += x;
    56         }
    57     }
    58     return ret;
    59 }
    60 int main(){
    61     k = read(); m = read(); n = read();
    62     clr(last,0); pt = edge;
    63     rep(i,1,n){
    64         rep(j,1,m){
    65             w[i][j] = read();
    66             pos[i][j][0] = ++N; pos[i][j][1] = ++N;
    67             add(pos[i][j][0],pos[i][j][1],1,-w[i][j]);
    68             add(pos[i][j][0],pos[i][j][1],INF,0);
    69         }
    70     }
    71     S = ++N; T = ++N;
    72     add(S,pos[1][1][0],k,0); add(pos[n][m][1],T,k,0);
    73     rep(i,1,n) rep(j,1,m){
    74         if (i + 1 <= n) add(pos[i][j][1],pos[i+1][j][0],INF,0);
    75         if (j + 1 <= m) add(pos[i][j][1],pos[i][j+1][0],INF,0);
    76     }
    77     printf("%d
    ",-mincost());
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/jimzeng/p/vijos1653.html
Copyright © 2011-2022 走看看