zoukankan      html  css  js  c++  java
  • LOJ #6008. 「网络流 24 题」餐巾计划

    #6008. 「网络流 24 题」餐巾计划 

    题目描述

    一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同。假设第 i ii 天需要 ri r_iri​​ 块餐巾。餐厅可以购买新的餐巾,每块餐巾的费用为 P PP 分;或者把旧餐巾送到快洗部,洗一块需 M MM天,其费用为 F FF 分;或者送到慢洗部,洗一块需 N NN 天,其费用为 S SS 分(S<F S < FS<F)。

    每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。

    试设计一个算法为餐厅合理地安排好 n nn 天中餐巾使用计划,使总的花费最小。

    输入格式

    第 1 11 行有 6 66 个正整数 n nn、P PP、M MM、F FF、N NN、S SS。

    n nn 是要安排餐巾使用计划的天数,P PP 是每块新餐巾的费用,M MM 是快洗部洗一块餐巾需用天数,F FF 是快洗部洗一块餐巾需要的费用,N NN 是慢洗部洗一块餐巾需用天数,S SS 是慢洗部洗一块餐巾需要的费用。

    接下来的 n nn 行是餐厅在相继的 n nn 天里,每天需用的餐巾数。

    输出格式

    输出餐厅在相继的 n nn 天里使用餐巾的最小总花费。

    样例

    样例输入

    3 10 2 3 3 2
    5
    6
    7

    样例输出

    145

    数据范围与提示

    1≤n≤1000 1 leq n leq 10001n1000

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 const int N = 5010;
     7 const int INF = 1e9;
     8 
     9 struct Edge{
    10     int u,v,f,c,nxt;
    11     Edge(){}
    12     Edge(int a,int b,int flow,int cost,int nt) { //-
    13         u = a;v = b;f = flow;c = cost;nxt = nt;
    14     }
    15 }e[100100];
    16 int head[N],dis[N],q[100100],pre[N];
    17 bool vis[N];
    18 int L,R,S,T,tot = 1,Mc,Mf;
    19 
    20 inline char nc() {
    21     static char buf[10010],*p1 = buf,*p2 = buf;
    22     return p1==p2&&(p2=(p1=buf)+fread(buf,1,10000,stdin),p1==p2)?EOF:*p1++;    
    23 }
    24 int read() {
    25     int x = 0,f = 1;char ch = nc();
    26     for (; ch<'0'||ch>'9'; ch=nc()) if (ch=='-')f=-1;
    27     for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
    28     return x*f;
    29 }
    30 void add_edge(int u,int v,int f,int c) {
    31     e[++tot] = Edge(u,v,f,c,head[u]);head[u] = tot;
    32     e[++tot] = Edge(v,u,0,-c,head[v]);head[v] = tot;
    33 }
    34 bool spfa() {
    35     for (int i=1; i<=T; ++i) vis[i]=false,dis[i]=INF;
    36     L = 1;R = 0;
    37     dis[S] = 0;
    38     q[++R] = S;vis[S] = true;pre[S] = 0;
    39     while (L <= R) {
    40         int u = q[L++];
    41         for (int i=head[u]; i; i=e[i].nxt) {
    42             int v = e[i].v;
    43             if (dis[v]>dis[u]+e[i].c && e[i].f > 0) {
    44                 dis[v] = dis[u] + e[i].c;
    45                 pre[v] = i;
    46                 if (!vis[v]) q[++R] = v,vis[v] = true;
    47             }
    48         }
    49         vis[u] = false;
    50     }
    51     return dis[T]!=INF;
    52 }
    53 void mcf() {
    54     int zf = INF;
    55     for (int i=T; i!=S; i=e[pre[i]].u) 
    56         zf = min(zf,e[pre[i]].f);
    57     for (int i=T; i!=S; i=e[pre[i]].u) 
    58         e[pre[i]].f -= zf,e[pre[i]^1].f += zf;
    59     Mf += zf;Mc += dis[T]*zf;
    60 }
    61 int main() {
    62     int n = read(),c = read(),kt = read(),kc = read(),mt = read(),mc = read();
    63     S = n*2+1;T = n*2+2;
    64     for (int t,i=1; i<=n; ++i) {
    65         t = read();
    66         add_edge(S,i,t,0);
    67         add_edge(i+n,T,t,0);
    68         add_edge(S,i+n,INF,c);
    69         if (i+kt<=n) add_edge(i,i+n+kt,INF,kc);
    70         if (i+mt<=n) add_edge(i,i+n+mt,INF,mc);
    71         if (i+1<=n) add_edge(i,i+1,INF,0);
    72     }
    73     while (spfa()) mcf();
    74     printf("%d",Mc);
    75     return 0;
    76 }
  • 相关阅读:
    遥远的国度(D12 树链剖分)
    Codechef DGCD Dynamic GCD(D12 树上GCD)
    html总结
    数据库大总结
    html笔记
    Linux常用快捷键
    进程
    多进程
    进程介绍
    网络并发
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8541749.html
Copyright © 2011-2022 走看看