• NOI2008志愿者招募


    P1588 - 【NOI2008】志愿者招募

    Description

    申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人。
    布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这并不是他的特长!于是布布找到了你,希望你帮他设计一种最 优的招募方案。

    Input

    第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。
    接下来的一行中包含N 个非负整数,表示每天至少需要的志愿者人数。
    接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了方便起见,我们可以认为每类志愿者的数量都是无限多的。

    Output

    包含一个整数,表示你所设计的最优方案的总费用。

    Sample Input

    3 3
    2 3 4
    1 2 2
    2 3 5
    3 3 2

    Sample Output

    14

    Hint

    【样例说明】
    招募3 名第一类志愿者和4 名第三类志愿者。 【数据规模和约定】
    30%的数据中,1 ≤ N, M ≤ 10,1 ≤ Ai ≤ 10;
    100%的数据中,1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均不超过2^31-1。

    Source

    NOI,数学 ,网络流 ,线性规划

    这是由等式 - >网络流的一个建模转化.根据提议列出若干个等式(或者是不等式,添加一个辅助变量变成等式),如果发现满足每个变量以正的负的形式都恰出现一次,即于每条边(u,v)若为Xi,Xi会在u的流量平衡条件式子(约束)中以正的形式出现一次,在v的流量平衡条件式子中以负的形式出现一次,这经常是网络流的流量平衡条件,可用网络流来做.

    参考博客:http://blog.sina.com.cn/s/blog_76f6777d0101bbcs.html

                     https://www.byvoid.com/zhs/blog/noi-2008-employee

         http://www.cnblogs.com/zzmmm/p/6658222.html

     1 #include<map>
     2 #include<set>
     3 #include<cmath>
     4 #include<ctime>
     5 #include<queue>
     6 #include<stack>
     7 #include<cstdio>
     8 #include<vector>
     9 #include<cstdlib>
    10 #include<cstring>
    11 #include<iomanip>
    12 #include<iostream>
    13 #include<algorithm>
    14 #define ll long long
    15 #define rep(i,a,b) for(register int i=a;i<=b;i++)
    16 #define inf 1<<30
    17 #define il inline
    18 #define re register
    19 using namespace std;
    20 const int N=1000+100,M=4*N*10;
    21 struct Edge{
    22     int fr,to,net;
    23     int cap,flow,cost;
    24     Edge() {}
    25     Edge(int u,int v,int c,int f,int w) : fr(u),to(v),cap(c),flow(f),cost(w) {}
    26 }e[M*2];
    27 int head[N],num_e,n,m,s,t;
    28 int d[N],a[N],p[N];
    29 bool inq[N];
    30 int demond[N];
    31 il int gi() {
    32     int ret=0,f=1;char ch=getchar();
    33     while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    34     if(ch=='-') f=-1,ch=getchar();
    35     while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    36     return ret*f;
    37 }
    38 void add(int u,int v,int c,int f,int w) {
    39     e[++num_e]=Edge(u,v,c,0,w);//  bug -w -> w
    40     e[num_e].net=head[u];head[u]=num_e;
    41     e[++num_e]=Edge(v,u,0,0,-w);
    42     e[num_e].net=head[v];head[v]=num_e;
    43 }
    44 bool spfa(int &cost) {
    45     rep(i,s,t) d[i]=inf;
    46     memset(inq,0,sizeof(inq));
    47     d[s]=0 , inq[s]=1 ,a[s]=inf, p[s]=0;// bug a[s]=0 - > a[s]=inf;
    48     queue<int> q;
    49     q.push(s);
    50     while(!q.empty()) {
    51         int u=q.front();q.pop();
    52         inq[u]=0;
    53         for(re int i=head[u];i!=-1;i=e[i].net) {            
    54             if(d[e[i].to]>d[u]+e[i].cost && e[i].cap>e[i].flow) {
    55                 p[e[i].to]=i;
    56                 d[e[i].to]=d[u]+e[i].cost;
    57                 a[e[i].to]=min(a[u],e[i].cap-e[i].flow);
    58                 if(!inq[e[i].to]) q.push(e[i].to),inq[e[i].to]=1;
    59             }
    60         }
    61     }
    62     if(d[t]==inf) return 0;
    63     cost += d[t] * a[t];
    64     for(re int u=t;u!=s;u=e[p[u]].fr) {
    65         e[p[u]].flow += a[t];
    66         e[p[u]^1].flow -= a[t];
    67     }
    68     return 1;
    69 }
    70 int MincostMaxflow() {
    71     int cost=0;
    72     while(spfa(cost));
    73     return cost;
    74 }
    75 int main() {
    76     n=gi(),m=gi();num_e=-1;memset(head,-1,sizeof(head));
    77     rep(i,1,n) demond[i]=gi();
    78     re int si,ti,ci;
    79     rep(i,1,m) {
    80         si=gi(),ti=gi(),ci=gi();
    81         add(si,ti+1,inf,0,ci);
    82     }n
    83     s=0,t=n+2;
    84     rep(i,1,n+1) {
    85         ci=demond[i]-demond[i-1];
    86         if(ci>=0) add(s,i,ci,0,0);
    87         else add(i,t,-ci,0,0);
    88         if(i>1) add(i,i-1,inf,0,0);
    89     }
    90     
    91     printf("%d",MincostMaxflow());
    92     return 0;
    93 }
  • 相关阅读:
    SCCM2012 R2实战系列之七:软件分发(exe)
    man 手册--nc
    挂载虚拟机磁盘文件
    bond模式详解
    Windows下计算md5值
    man手册--iostat
    mount---挂载文件系统
    Linux-swap分区
    sync---强制将被改变的内容立刻写入磁盘
    vmstat---有关进程、虚存、页面交换空间及 CPU信息
  • 原文地址:https://www.cnblogs.com/ypz999/p/6678099.html
Copyright © 2020-2023  润新知