zoukankan      html  css  js  c++  java
  • POJ3422简单费用流

    题意:
         给一个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 " ,Ans);
        }
         return 0;
    }













  • 相关阅读:
    通过docker把本地AspNetCore WebAPI镜像打包到阿里云镜像仓库并在centos部署
    记一次Java AES 加解密 对应C# AES加解密 的一波三折
    .Net Core MVC实现自己的AllowAnonymous
    Net Core 中间件实现修改Action的接收参数及返回值
    手把手教你实现自己的abp代码生成器
    C# 实现Jwtbearer Authentication
    vs2017调试浏览器闪退
    ABP 邮箱设置
    FastJson反序列化获取不到值
    内网环境下搭建maven私服小技巧
  • 原文地址:https://www.cnblogs.com/csnd/p/12062599.html
Copyright © 2011-2022 走看看