• 洛谷 P2045 方格取数加强版【费用流】


     
     
    题目链接:https://www.luogu.org/problemnew/show/P2045

    题目描述

    给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大

    输入输出格式

    输入格式:

    第一行两个数n,k(1<=n<=50, 0<=k<=10)

    接下来n行,每行n个数,分别表示矩阵的每个格子的数

    输出格式:

    一个数,为最大和

    输入输出样例

    输入样例#1:
    3 1
    1 2 3
    0 2 1
    1 4 2
    输出样例#1:
    11

    说明

    每个格子中的数不超过1000

    题解:和昨天那题略像,就是限制点了,拆点再跑费用流。。。不写了,我上课去......

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N = 5010;//注意点数
     5 const int M = N*8+10;
     6 const int INF = 0x3f3f3f3f;
     7 struct Edge { int to,next,cap,flow,cost; }edge[M];
     8 int head[N],tol;
     9 int pre[N],dis[N];
    10 bool vis[N];
    11 int V;      
    12 void init(int n) {
    13     V = n;
    14     tol = 0;
    15     memset(head,-1,sizeof(head));
    16 }
    17 void addedge(int u,int v,int cap,int cost) {
    18     edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++;
    19     edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;
    20 }
    21 bool spfa(int s,int t) {
    22     queue<int>q;
    23     for(int i = 0;i < V;i++) {
    24         dis[i] = INF;
    25         vis[i] = false;
    26         pre[i] = -1;
    27     }
    28     dis[s] = 0;
    29     vis[s] = true;
    30     q.push(s);
    31     while(!q.empty()) {
    32         int u = q.front();
    33         q.pop();
    34         vis[u] = false;
    35         for(int i = head[u]; i != -1;i = edge[i].next) {
    36             int v = edge[i].to;
    37             if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) {
    38                 dis[v] = dis[u] + edge[i].cost;
    39                 pre[v] = i;
    40                 if(!vis[v]) {
    41                     vis[v] = true;
    42                     q.push(v);
    43                 }
    44             }
    45         }
    46     }
    47     if(pre[t] == -1) return false;
    48     else return true;
    49 }
    50 int minCostMaxflow(int s,int t,int &cost) {
    51     int flow = 0;
    52     cost = 0;
    53     while(spfa(s,t)) {
    54         int Min = INF;
    55         for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) {
    56             if(Min > edge[i].cap - edge[i].flow)
    57                 Min = edge[i].cap - edge[i].flow;
    58         }
    59         for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) {
    60             edge[i].flow += Min;
    61             edge[i^1].flow -= Min;
    62             cost += edge[i].cost * Min;
    63         }
    64         flow += Min;
    65     }
    66     return flow;
    67 }
    68 int main() {
    69     int n, k, i, j, x, ans = 0;
    70     scanf("%d%d", &n, &k);
    71     init(n*n*2+3);
    72 
    73     int s = n*n*2+1, t = n*n*2+2;
    74 
    75     for(i = 1; i <= n; ++i) {//拆点限流
    76         for(j = 1; j <= n; ++j) {
    77             scanf("%d", &x);
    78             addedge((i-1)*n+j, (i-1)*n+j + n*n, 1, -x);//存负权
    79             if(k > 1) addedge((i-1)*n+j, (i-1)*n+j + n*n, k-1, 0);//注意判断
    80         }
    81     }
    82     for(i = 1; i <= n ;++i) {//向右加边
    83         for(j = 1; j < n; ++j) {
    84             addedge((i-1)*n+j + n*n, (i-1)*n+j+1, k, 0);
    85         }
    86     }
    87     for(i = 1; i < n; ++i) {//向下加边
    88         for(j = 1; j <= n; ++j) {
    89             addedge((i-1)*n+j + n*n, (i-1)*n+j+n, k, 0);
    90         }
    91     }
    92     //源点、汇点 与 起点、终点连边
    93     addedge(s, 1, k, 0);
    94     addedge(n*n*2, t, k, 0);
    95 
    96     minCostMaxflow(s, t, ans);
    97     printf("%d
    ", -ans);
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    WebApi开启CORS支持跨域POST
    VueJs生产环境部署
    VueJs开发笔记—IDE选择和优化、框架特性、数据调用、路由选项及使用
    微信分享JSSDK-invalid signature签名错误的解决方案
    关于后台系统自动生成的一点思考
    编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]
    编写高质量代码改善C#程序的157个建议[10-12]
    编写高质量代码改善C#程序的157个建议[4-9]
    编写高质量代码改善C#程序的157个建议[正确操作字符串、使用默认转型方法、却别对待强制转换与as和is]
    Oracle初级索引学习总结
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/9039340.html
Copyright © 2020-2023  润新知