zoukankan      html  css  js  c++  java
  • 1061: [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。

    首先贴上别人的题解https://www.byvoid.com/blog/noi-2008-employee/

    首先肯定都知道这个是线性规划,可以用单纯形法做,但是单纯形法好像很少用一样,反正我是不会

    既然不会线性规划,我们只好转换成网络流了,因为网络流也是一种线性规划我就不说什么了,弱菜表示完全想不到.....,线性规划转化为网络流,完全不懂啊

      1 const
      2         maxn=1010;
      3         maxm=40010;
      4         inf=100000000;
      5 var
      6         a,flag,dis,f,first:array[0..maxn]of longint;
      7         next,last,w,liu:array[0..maxm]of longint;
      8         n,m,s,t,tot,time,ans,flow:longint;
      9  
     10 procedure insert(u,v,f,l:longint);
     11 begin
     12         inc(tot);
     13         last[tot]:=v;
     14         next[tot]:=first[u];
     15         w[tot]:=f;
     16         liu[tot]:=l;
     17         first[u]:=tot;
     18         inc(tot);
     19         last[tot]:=u;
     20         next[tot]:=first[v];
     21         w[tot]:=-f;
     22         first[v]:=tot;
     23 end;
     24  
     25 procedure init;
     26 var
     27         i,j,x,y,z:longint;
     28 begin
     29         read(n,m);
     30         tot:=1;
     31         for i:=1 to n do
     32           read(a[i]);
     33         for i:=1 to m do
     34           begin
     35             read(x,y,z);
     36             insert(x,y+1,z,inf);
     37           end;
     38         s:=0;
     39         t:=n+2;
     40         for i:=1 to n+1 do
     41           begin
     42             z:=a[i]-a[i-1];
     43             if z>0 then insert(s,i,0,z);
     44             if z<0 then insert(i,t,0,-z);
     45             if i>0 then insert(i,i-1,0,inf);
     46           end;
     47 end;
     48  
     49 function dfs(x,flow:longint):longint;
     50 var
     51         i,d,min:longint;
     52 begin
     53         if x=t then
     54         begin
     55           inc(ans,flow*dis[t]);
     56           exit(flow);
     57         end;
     58         i:=first[x];
     59         flag[x]:=time;
     60         dfs:=0;
     61         while i<>0 do
     62           begin
     63             d:=dis[x]+w[i]-dis[last[i]];
     64             min:=flow;
     65             if min>liu[i] then min:=liu[i];
     66             if (min>0) and (d<f[last[i]]) then f[last[i]]:=d;
     67             if (min>0) and (d=0) and (flag[last[i]]<>time) then
     68             begin
     69               d:=dfs(last[i],min);
     70               inc(dfs,d);
     71               dec(flow,d);
     72               dec(liu[i],d);
     73               inc(liu[i xor 1],d);
     74             end;
     75             if flow=0 then break;
     76             i:=next[i];
     77           end;
     78 end;
     79  
     80 procedure work;
     81 var
     82         i,del:longint;
     83 begin
     84         repeat
     85           inc(time);
     86           for i:=s to t do
     87             f[i]:=inf;
     88           inc(flow,dfs(s,inf));
     89           del:=inf;
     90           for i:=s to t do
     91             if (flag[i]<>time) and (del>f[i]) then del:=f[i];
     92           if del=inf then break;
     93           for i:=s to t do
     94             if flag[i]<>time then inc(dis[i],del);
     95         until false;
     96         write(ans);
     97 end;
     98  
     99 var
    100         q:array[0..maxn]of longint;
    101         head,tail:longint;
    102  
    103 procedure spfa;
    104 var
    105         i:longint;
    106 begin
    107         inc(time);
    108         head:=1;
    109         tail:=2;
    110         fillchar(dis,sizeof(dis),1);
    111         q[1]:=s;
    112         dis[s]:=0;
    113         while head<>tail do
    114           begin
    115             i:=first[q[head]];
    116             while i<>0 do
    117               begin
    118                 if (liu[i]>0) and (dis[last[i]]>dis[q[head]]+w[i]) then
    119                 begin
    120                   if flag[last[i]]<>time then
    121                   begin
    122                     q[tail]:=last[i];
    123                     flag[last[i]]:=time;
    124                     tail:=tail mod maxn+1;
    125                   end;
    126                   dis[last[i]]:=dis[q[head]]+w[i];
    127                 end;
    128                 i:=next[i];
    129               end;
    130             flag[q[head]]:=time-1;
    131             head:=head mod maxn+1;
    132           end;
    133 end;
    134  
    135 begin
    136         init;
    137        spfa;
    138         work;
    139 end.
    View Code
  • 相关阅读:
    进程提权小结
    进程工作集WorkingSet (PSAPI 01)
    GetSystemInfo 和 GlobalMemoryStatus获取系统信息,内存信息
    C++11智能指针 share_ptr,unique_ptr,weak_ptr用法
    结构体及类对象的内存对齐
    菱形继承问题和虚继承
    TLS反调试
    获取程序目录,模块路径
    docker install for centos7
    docker镜像与容器概念
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3662732.html
Copyright © 2011-2022 走看看