1061: [Noi2008]志愿者招募 - BZOJ

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

 

你可能感兴趣的:(2008)