zoukankan      html  css  js  c++  java
  • 洛谷 P1251 餐巾计划问题(线性规划网络优化)【费用流】

    (题外话:心塞...大部分时间都在debug,拆点忘记加N,总边数算错,数据类型标错,字母写错......)

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

    洛谷 P1251 餐巾计划问题

    输入输出样例

    输入样例#1:
    3
    1 7 5 
    11 2 2 3 1
    
    输出样例#1:
    134
    

    说明

    N<=2000

    ri<=10000000

    p,f,s<=10000

    时限4s

    题解:拆点再跑费用流呗,第i天拆成Xi(脏的餐巾)和Yi(干净的餐巾)。对于每天情况,建图示例如下(解释详见代码注释):

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N = 4005;
     5 const int M = 24005;
     6 const ll INF = 1e18;
     7 const int INF2 = 1e9;
     8 struct Edge { int to,next,cap,flow,cost; }edge[M];
     9 int head[N],tol;
    10 int pre[N];
    11 ll dis[N];
    12 bool vis[N];
    13 int V;
    14 void init(int n) {
    15     V = n;
    16     tol = 0;
    17     memset(head,-1,sizeof(head));
    18 }
    19 void addedge(int u,int v,int cap,int cost) {
    20     edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++;
    21     edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;
    22 }
    23 bool spfa(int s,int t) {
    24     queue<int>q;
    25     for(int i = 0;i < V;i++) {
    26         dis[i] = INF;
    27         vis[i] = false;
    28         pre[i] = -1;
    29     }
    30     dis[s] = 0;
    31     vis[s] = true;
    32     q.push(s);
    33     while(!q.empty()) {
    34         int u = q.front();
    35         q.pop();
    36         vis[u] = false;
    37         for(int i = head[u]; i != -1;i = edge[i].next) {
    38             int v = edge[i].to;
    39             if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) {
    40                 dis[v] = dis[u] + edge[i].cost;
    41                 pre[v] = i;
    42                 if(!vis[v]) {
    43                     vis[v] = true;
    44                     q.push(v);
    45                 }
    46             }
    47         }
    48     }
    49     if(pre[t] == -1) return false;
    50     else return true;
    51 }
    52 ll minCostMaxflow(int s,int t,ll &cost) {
    53     ll flow = 0;
    54     cost = 0;
    55     while(spfa(s,t)) {
    56         ll Min = INF;
    57         for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) {
    58             if(Min > edge[i].cap - edge[i].flow)
    59                 Min = edge[i].cap - edge[i].flow;
    60         }
    61         for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) {
    62             edge[i].flow += Min;
    63             edge[i^1].flow -= Min;
    64             cost += edge[i].cost * Min;
    65         }
    66         flow += Min;
    67     }
    68     return flow;
    69 }
    70 int main() {
    71     int n, r, i, j, p, m, f, nn, s;
    72     ll ans = 0;
    73     scanf("%d", &n);
    74     init(n*2+3);
    75 
    76     int S = n*2+1, T = n*2+2;
    77 
    78     for(i = 1; i <= n; ++i) {
    79         scanf("%d", &r);//每天需要餐巾数
    80         addedge(S, i, r, 0);
    81         addedge(i+n, T, r, 0);
    82     }
    83     scanf("%d%d%d%d%d", &p, &m, &f, &nn, &s);
    84     for(i = 1; i <= n; ++i) {
    85         addedge(S, i+n, INF2, p);//购买新餐巾
    86         if(i+m<=n) addedge(i, i+m+n, INF2, f);//快洗
    87         if(i+nn<=n) addedge(i, i+nn+n, INF2, s);//慢洗
    88         if(i!=n) addedge(i, i+1, INF2, 0);//留到第二天
    89     }
    90 
    91     minCostMaxflow(S, T, ans);
    92     printf("%lld
    ", ans);
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    读javascript高级程序设计08-引用类型之Global、Math、String
    读javascript高级程序设计07-引用类型、Object、Array
    读javascript高级程序设计06-面向对象之继承
    读javascript高级程序设计05-面向对象之创建对象
    读javascript高级程序设计04-canvas
    读javascript高级程序设计03-函数表达式、闭包、私有变量
    读javascript高级程序设计02-变量作用域
    C#将Word转换成PDF方法总结(基于Office和WPS两种方案)
    【转】 C#中Finally的一个不太常见的用法
    一看就懂的ReactJs入门教程-精华版
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/9038377.html
Copyright © 2011-2022 走看看