题意:

     给一个n*n的矩阵,从左上角走到右下角,的最大收益,可以走k次,每个格子的价值只能取一次,但是可以走多次。

思路:

      比较简单的一个费用流题目,直接拆点,拆开的点之间连接两条边,一条是流量1费用是这个点的价值,另一条是流量k-1费用是0,然后就是当前这个点连接右下方的点,然后在虚拟出超级远点和汇点限流用的,比较简单,不解释了。

#include<stack>

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 5100

#define N_edge 200000

#define INF 1000000000

using namespace std;

typedef struct

{

    int from ,to ,cost ,flow ,next;

}STAR;

STAR E[N_edge];

int list[N_node] ,tot;

int s_x[N_node] ,mer[N_node];

void add(int a ,int b ,int c ,int d)

{

    E[++tot].from = a;

    E[tot].to = b;

    E[tot].cost = c;

    E[tot].flow = d;

    E[tot].next = list[a];

    list[a] = tot;

    E[++tot].from = b;

    E[tot].to = a;

    E[tot].cost = -c;

    E[tot].flow = 0;

    E[tot].next = list[b];

    list[b] = tot;

}

bool spfa(int s ,int t ,int n)

{

    for(int i = 0 ;i <= n ;i ++)

    s_x[i] = -INF;

    int mark[N_node] = {0};

    queue<int>q;

    q.push(s);

    s_x[s] = 0;

    mark[s] = 1;

    memset(mer ,255 ,sizeof(mer));

    while(!q.empty())

    {

        int xin ,tou;

        tou = q.front();

        q.pop();

        mark[tou] = 0;

        for(int k = list[tou] ;k ;k = E[k].next)

        {

            xin = E[k].to;

            if(s_x[xin] < s_x[tou] + E[k].cost && E[k].flow)

            {

                s_x[xin] = s_x[tou] + E[k].cost;

                mer[xin] = k;

                if(!mark[xin])

                {

                    mark[xin] = 1;

                    q.push(xin);

                }

            }

        }

    }

    return mer[t] != -1;

}

int M_M_Flow(int s ,int t ,int n)

{

    int maxflow = 0 ,maxcost = 0 ,minflow;

    while(spfa(s ,t ,n))

    {

        minflow = INF;

        for(int i = mer[t] ;i + 1 ;i = mer[E[i].from])

        if(minflow > E[i].flow) minflow = E[i].flow;

        for(int i = mer[t] ;i + 1 ;i = mer[E[i].from])

        {

            E[i].flow -= minflow;

            E[i^1].flow += minflow;

            maxcost += minflow * E[i].cost;

        }

        maxflow += minflow;

    }

    return maxcost;

}

int main ()

{

    int n ,k ,i ,j ,Ans ,num;

    while(~scanf("%d %d" ,&n ,&k))

    {

        memset(list ,0 ,sizeof(list)) ,tot = 1;

        for(i = 1 ;i <= n ;i ++)

        for(j = 1 ;j <= n ;j ++)

        {

            scanf("%d" ,&num);

            add((i - 1) * n + j ,(i - 1) * n + j + n * n ,num ,1);

            add((i - 1) * n + j ,(i - 1) * n + j + n * n ,0 ,k - 1);

        }

        add(0 ,1 ,0 ,k);

        for(i = 1 ;i <= n ;i ++)

        for(j = 1 ;j <= n ;j ++)

        {

            if(i <= n - 1) add((i - 1) * n + j + n * n ,i * n + j ,0 ,k);

            if(j <= n - 1) add((i - 1) * n + j + n * n ,(i - 1) * n + j + 1 ,0 ,k);

        }

        add(n * n * 2 ,n * n * 2 + 1 ,0 ,k);

        Ans = M_M_Flow(0 ,n * n * 2 + 1 ,n * n * 2 + 1);

        printf("%d\n" ,Ans);

    }

     return 0;

}

最新文章

  1. pt-heartbeat
  2. eclipse软件创建servlet
  3. 解决.NET WebService引用后添加HTTP Header的问题
  4. [转]Struts2.3.16.1+Hibernate4.3.4+Spring4.0.2 框架整合
  5. C# 中excel操作
  6. 《DSP using MATLAB》示例Example5.4
  7. JQuery 表单校验插件 validate 使用纪录
  8. 日常工作生活中的做人做事道理[持续更新ing]
  9. 通过JAVA代码获取手机的一些基本信息(本机号码,SDK版本,系统版本,手机型号)
  10. PCA主成分分析方法
  11. 阿里云centos 安装和配置 DokuWiki
  12. unlink()
  13. jQuery中$(function()与(function($)等的区别详细讲解
  14. eclips环境下开发spring boot项目,application.properties配置文件下中文乱码解决方案
  15. [No0000183]Parallel Programming with .NET-How PLINQ processes an IEnumerable&lt;T&gt; on multiple cores
  16. Writing device drivers in Linux: A brief tutorial
  17. 7.3 netty3基本使用
  18. solr建立pdf/word/excel索引的方法
  19. kali linux之msf后渗透阶段
  20. PAT——1040. 有几个PAT

热门文章

  1. 基于Hi3559AV100 RFCN实现细节解析-(3)系统输入VI分析一 :
  2. Web微信协议
  3. YoloV3 记录
  4. PTE 准备之 Repeat sentence
  5. swing实现QQ登录界面1.0( 实现了同一张图片只加载一次)、(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件)
  6. sqli-labs系列——第一关
  7. 创建数据库 UTF-8
  8. Java单链表反转图文详解
  9. Markdown部分用法总结
  10. 树结构系列(三):B树、B+树