【Luogu】P2488工作安排(费用流)
这题……费用流即可……(哇啊要被打死辣)
然而我printf("%d")爆零四次
好的心如死灰
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<algorithm> #include<queue> #define maxn 1000010 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct Edge{ long long next,from,to,val,dis; }edge[maxn*2]; long long head[maxn],num; inline void addedge(long long from,long long to,long long val,long long dis){ edge[++num]=(Edge){head[from],from,to,val,dis}; head[from]=num; } inline void add(long long from,long long to,long long val,long long dis){ addedge(from,to,val,dis); addedge(to,from,0,-dis); } inline long long count(long long i){ return i&1?i+1:i-1; } long long Start,End; long long dis[maxn]; bool vis[maxn]; long long pre[maxn]; long long flow[maxn]; long long spfa(){ memset(dis,127/2,sizeof(dis)); dis[Start]=0; flow[Start]=dis[1]; memset(pre,0,sizeof(pre)); queue<long long>q; q.push(Start); while(!q.empty()){ long long from=q.front();q.pop(); vis[from]=0; if(flow[from]==0) continue; for(long long i=head[from];i;i=edge[i].next){ long long to=edge[i].to; if(dis[to]<=dis[from]+edge[i].dis||edge[i].val<=0) continue; dis[to]=dis[from]+edge[i].dis; pre[to]=i; flow[to]=min(flow[from],edge[i].val); if(vis[to]) continue; vis[to]=1; q.push(to); } } if(pre[End]==0) return 0; long long now=End; while(now!=Start){ long long ret=pre[now]; edge[ret].val-=flow[End]; edge[count(ret)].val+=flow[End]; now=edge[ret].from; } return dis[End]*flow[End]; } long long s[maxn]; int main(){ long long m=read(),n=read();End=n+m+1; for(long long i=1;i<=n;++i){ long long x=read(); add(i+m,End,x,0); } for(long long i=1;i<=m;++i) for(long long j=1;j<=n;++j){ long long x=read(); if(x) add(i,j+m,0x7fffffff,0); } for(long long i=1;i<=m;++i){ long long sum=read(); for(long long j=1;j<=sum;++j) s[j]=read(); for(long long j=1;j<=sum;++j){ long long x=read(); add(Start,i,s[j]-s[j-1],x); } long long x=read(); add(Start,i,0x7fffffff,x); } long long ans=0; while(1){ long long now=spfa(); if(now==0) break; ans+=now; } printf("%lld",ans); return 0; }