设 Si S i 为第 i i 天可以工作的志愿者的种类集合, xj x j 为第 j j 种志愿者招募的个数,那么我们可以得到若干形如:
#include
using namespace std;
#define RI register int
int read() {
int q=0;char ch=' ';
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
return q;
}
typedef long long LL;
const int N=1005,M=1000005,inf=0x3f3f3f3f;
int n,m,tot=1,S,T,ans;
int a[N],h[N],ne[M],to[M],flow[M],w[M],l[N],r[N];
int dis[N],pre[N],liu[N],inq[N];
void add(int x,int y,int z,int c) {
to[++tot]=y,ne[tot]=h[x],h[x]=tot,flow[tot]=z,w[tot]=c;
to[++tot]=x,ne[tot]=h[y],h[y]=tot,flow[tot]=0,w[tot]=-c;
}
int bfs() {
for(RI i=S;i<=T;++i) dis[i]=0x3f3f3f3f,pre[i]=inq[i]=0;
queue<int> q;
dis[S]=0,liu[S]=inf,q.push(S);
while(!q.empty()) {
int x=q.front();q.pop(),inq[x]=0;
for(RI i=h[x];i;i=ne[i])
if(flow[i]>0&&dis[x]+w[i]if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
}
}
if(!pre[T]) return 0;
ans+=liu[T]*dis[T];int x=T;
while(x) {
int kl=pre[x];
flow[kl]-=liu[T],flow[kl^1]+=liu[T],x=to[kl^1];
}
return 1;
}
int main()
{
int x,num;
n=read(),m=read();
S=0,T=n+1;
add(S,1,inf,0);
for(RI i=1;i<=n;++i) add(i,i+1,inf-read(),0);
for(RI i=1;i<=m;++i) {
num=read();
for(RI j=1;j<=num;++j) l[j]=read(),r[j]=read();
x=read();
for(RI j=1;j<=num;++j) add(l[j],r[j]+1,inf,x);
}
while(bfs());
printf("%d\n",ans);
return 0;
}