题意比较简单。。
建图时, X为天数, Y为女孩。 二分图的构图方式。。
之后添加源点跟汇点, 再添加附加源点跟汇点。。
先连接 des, src 正无穷的边, 跑无源无汇可行流, 这时候判断流量是否是符合要求的。。
如果符合要求,则 去除掉 s,t这两个点以及连接他们的边, 之后跑 src到des的最大流,把残留的流量压过去,
残留图里剩下的就是最大的方案了。。
注意最终答案是 src 到des的全部残留流量的和。。
//tpl
//ipqhjjybj_tpl.h
//header.h
#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <sstream>
#include <math.h>
#define mp(x,y) make_pair(x,y)
#define pii pair<int,int>
#define pLL pair<long long ,long long>
#define pb(x) push_back(x)
#define rep(i,j,k) for(int i = j; i < k;i++)
#define MAX(x,a) x=((x)<(a))?(a):(x)
#define MIN(x,a) x=((x)>(a))?(a):(x)
using namespace std;
const int N = 1500;
int n,m,tot;
int s,t;
int sum;
struct node{
int u,v,w,next;
int kk;
node(){}
node(int _u,int _v,int _w,int _next){
u=_u,v=_v,w=_w,next=_next;
}
}edge[N*500];
int head[N],cur[N],dis[N];
int pre[N],gap[N],aug[N];
const int oo=0x3f3f3f3f;
void addEdge(int u,int v,int w,int _zz){
edge[tot]=node(u,v,w,head[u]);
head[u]=tot++;
edge[tot]=node(v,u,0,head[v]);
edge[tot].kk = _zz;
head[v]=tot++;
}
int SAP(int s,int e,int n){
int max_flow=0,v,u=s;
int id,mindis;
aug[s]=oo;
pre[s]=-1;
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
gap[0]=n;
for(int i=0;i <= n;i++)
cur[i]=head[i];
while(dis[s]<n){
if(u==e){
max_flow += aug[e];
for(v=pre[e]; v!=-1; v=pre[v]){
int ed=cur[v];
edge[ed].w -= aug[e];
edge[ed^1].w += aug[e];
aug[v]-=aug[e];
if(edge[ed].w==0) u=v;
}
}
bool flag=false;
for(id=cur[u]; id!=-1;id=edge[id].next){
v=edge[id].v;
if(edge[id].w > 0 && dis[u]==dis[v]+1){
flag=true;
pre[v]=u;
cur[u]=id;
aug[v]=min(aug[u],edge[id].w);
u=v;
break;
}
}
if(flag==false){
if(--gap[dis[u]] == 0) break;
int mindis=n;
for(id=head[u]; id!=-1; id=edge[id].next){
v=edge[id].v;
if(edge[id].w>0 && dis[v] < mindis){
mindis = dis[v];
cur[u]=id;
}
}
dis[u] = mindis + 1;
gap[dis[u]]++;
if(u!=s)u=pre[u];
}
}
return max_flow;
}
int girl[N],day[N];
int in[N];
int fs;
// 二部分
// X 每天 Y 女孩
int solve(){
int src = s, des = t;
s = des+1;t = s+1;
int en0 = tot;
int max_flow=0;
rep(i,0,des+1){
if(in[i]>0) addEdge(s,i,in[i],0),max_flow+=in[i];
else if(in[i]<0) addEdge(i,t,-in[i],0);
}
// SAP(s,t,t+1);
addEdge(des,src,oo,0);
int s1 = SAP(s,t,t+1);
if(s1== max_flow){
rep(i,0,des+1)
while(head[i]>=en0)
head[i]=edge[head[i]].next;
SAP(src,des,des+1);
int ret = 0;
for(int i = head[src];i!=-1;i=edge[i].next)
ret += edge[i^1].w;
return ret;
}else return -1;
}
void print(){
for(int i = 1;i < fs;i+=2)
printf("%d\n",edge[i].w+edge[i].kk);
// printf("fs=%d\n",fs);
}
int main(){
while(scanf("%d %d",&n,&m)!=EOF){
memset(head,-1,sizeof(head));
memset(in,0,sizeof(in));
s = sum = tot = 0;
t = n+m+1;
rep(i,1,m+1)scanf("%d",girl+i);
rep(i,1,n+1){
int nt;
scanf("%d %d",&nt,&day[i]);
while(nt--){
int tar,l,r;
scanf("%d %d %d",&tar,&l,&r);
tar++;
in[tar+n] += l;
in[i] -= l;
addEdge(i,tar+n,r-l,l);
}
}
fs = tot;
rep(i,1,n+1)addEdge(s,i,day[i],0);
rep(i,1,m+1)addEdge(n+i,t,oo,0),in[t]+=girl[i],in[n+i]-=girl[i];
int ans=-1;
if((ans=solve()) >= 0){
printf("%d\n",ans);
print();
}else printf("-1\n");
printf("\n");
}
return 0;
}