BZOJ1061 [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

1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。

正解:最小费用最大流

解题报告:完全不知道怎样建图,在网上查了题解,大概是这样,一个点向后一个点连边,容量为inf-a[i],费用为0,然后对于每一个买人的操作,从l到r+1连一个容量为inf,费用为输入费用的边,直接跑最小费用最大流。

 

 1 #include <iostream>
 2 #include <iomanip>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <string>
 8 #include <algorithm>
 9 #define int long long
10 #define RG register
11 #define MIN(a,b) a<b?a:b
12 const int N = 100000;
13 const int M = 1000000;
14 const int inf = 914748364121474836;
15 
16 using namespace std;
17 
18 int head[N],a[N],nxt[N],f[M],vis[N];
19 int cnt=1,S,T,ans,y=inf,dis[N],fa[N];
20 
21 int gi(){
22     char ch=getchar();int x=0;
23     while(ch<'0' || ch>'9') ch=getchar();
24     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
25     return x;
26 }
27 
28 struct date{
29     int from,to,val,s;
30 }nn[N];
31 
32 void link(int l,int r,int val,int s){
33     nn[++cnt]=(date){l,r,val,s},nxt[cnt]=head[l],head[l]=cnt;
34     nn[++cnt]=(date){r,l,0,-s},nxt[cnt]=head[r],head[r]=cnt;
35     return;
36 }
37 
38 int spfa(){
39     for (RG int i=S; i<=T; ++i) dis[i]=inf;
40     int l=0,r=1;
41     f[1]=0,dis[0]=0,vis[0]=1;
42     while(l<r){
43         ++l;
44         for (RG int i=head[f[l]]; i; i=nxt[i])
45             if (nn[i].val && dis[f[l]]+nn[i].s<dis[nn[i].to]){
46                 dis[nn[i].to]=dis[f[l]]+nn[i].s;
47                 fa[nn[i].to]=i;
48                 if (vis[nn[i].to]==0)
49                     f[++r]=nn[i].to,vis[nn[i].to]=1;
50             }
51         vis[f[l]]=0;
52     }
53     int gg=inf;
54     for (RG int i=fa[T]; i; i=fa[nn[i].from]) gg=MIN(gg,nn[i].val);
55     gg=MIN(gg,y);y-=gg;
56     ans+=dis[T]*gg;
57     if (y==0) return 0;
58     for (RG int i=fa[T]; i; i=fa[nn[i].from]) nn[i].val-=gg,nn[i^1].val+=gg;
59     return 1;
60 }
61 
62 main(){
63     freopen("x.in","r",stdin);
64     freopen("x.out","w",stdout);
65     int n=gi(),m=gi();T=n+1;
66     for (RG int i=1; i<=n; ++i) a[i]=gi();
67     link(S,1,inf,0);
68     for (RG int i=1; i<=n; ++i) link(i,i+1,inf-a[i],0);
69     for (RG int i=1; i<=m; ++i){
70         RG int l=gi(),r=gi(),s=gi();
71         link(l,r+1,inf,s);
72     }
73     while(spfa());
74     printf("%lld",ans);
75     return 0;
76 }

 

posted @ 2017-02-22 17:19  Cjk_2001  阅读(218)  评论(1编辑  收藏  举报