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

 

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

 
 
这题的网络流建模太神了。。。大神们都是怎么想到的啊。。。我无论怎么想都开不出这么大的脑洞。。。。
https://www.byvoid.com/blog/noi-2008-employee/
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 #include<string>
 8 #include<map>
 9 #include<queue>
10 #include<vector>
11 #include<set>
12 #define inf 1000000000
13 #define maxn 1005
14 #define maxm 50005
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
22 using namespace std;
23 int read(){
24     int x=0,f=1;char ch=getchar();
25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
27     return x*f;
28 }
29 int n,m,tot=1,ans;
30 int head[maxn],q[maxn],d[maxn],from[maxn];
31 bool inq[maxn];
32 struct edge{
33     int go,next,from,w,c;
34 }e[maxm];
35 void insert(int u,int v,int w,int c){
36     e[++tot]=(edge){v,head[u],u,w,c};head[u]=tot;
37 }
38 void ins(int u,int v,int w,int c){
39     insert(u,v,w,c);insert(v,u,0,-c);
40 }
41 bool spfa(){
42     int h=0,t=1;
43     for0(i,maxn)d[i]=inf;
44     q[h]=0;d[0]=0;inq[0]=1;
45     while(h!=t){
46         int x=q[h++];if(h==maxn)h=0;
47         for4(i,x)
48             if(e[i].w&&d[x]+e[i].c<d[y]){
49                 d[y]=d[x]+e[i].c;
50                 from[y]=i;
51                 if(!inq[y]){
52                     inq[y]=1;
53                     q[t++]=y;
54                     if(t==maxn)t=0;
55                 }
56             }
57         inq[x]=0;
58     }
59     if(d[maxn]==inf)return 0;
60     else return 1;
61 }
62 void mcf(){
63     int x=inf;
64     for(int i=from[maxn];i;i=from[e[i].from])
65         x=min(x,e[i].w);
66     for(int i=from[maxn];i;i=from[e[i].from]){
67         e[i].w-=x;e[i^1].w+=x;ans+=e[i].c*x;
68     }
69 }
70 int main(){
71     //freopen("input.txt","r",stdin);
72     //freopen("output.txt","w",stdout);
73     n=read();m=read();
74     int l=0,r;
75     for1(i,n){
76         r=read();
77         int x=r-l;  
78         if(x>0)ins(0,i,x,0);
79         else ins(i,maxn,-x,0);
80         ins(i+1,i,inf,0);
81         l=r;
82     }
83     ins(n+1,maxn,l,0);
84     for1(i,m){
85         int x=read(),y=read(),z=read();
86         ins(x,y+1,inf,z);
87     }
88     while(spfa())mcf();
89     printf("%d",ans);
90     return 0;
91 }
View Code

 

posted @ 2016-05-24 16:41  HTWX  阅读(94)  评论(0编辑  收藏  举报