题意以及分析:http://ycool.com/post/zhhrrm6#rule3
主要是建图,简化图,然后在套最大流的模板。
#include <iostream> #include<string.h> #include<cstdio> using namespace std; struct Node { int v,cap,flow,next; Node(){} Node(int _v,int _cap,int _flow,int _next) { v=_v; cap=_cap; flow=_flow; next=_next; } }; const int INF=1000000000; Node edges[120005]; int pig[1005],a[1005][105]; int n,m,s,t,head[1005],e; void Add(int u,int v,int cap) { edges[e]=Node(v,cap,0,head[u]); head[u]=e++; edges[e]=Node(u,0,0,head[v]); head[v]=e++; } int num[1005],h[1005],curedge[1005],pre[1005]; int Maxflow(int s,int t,int n) { int ans=0,i,k,x,d,u; memset(num,0,sizeof(num)); memset(h,0,sizeof(h)); for(i=0;i<=n;i++) curedge[i]=head[i]; num[n]=n;u=s; while(h[u]<n) { if(u==t) { d=INF+1; for(i=s;i!=t;i=edges[curedge[i]].v) if(d>edges[curedge[i]].cap) k=i,d=edges[curedge[i]].cap; for(i=s;i!=t;i=edges[curedge[i]].v) { x=curedge[i]; edges[x].cap-=d; edges[x].flow+=d; edges[x^1].cap+=d; edges[x^1].flow-=d; } ans+=d;u=k; } for(i=curedge[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[u]==h[edges[i].v]+1) break; if(i!=-1) { curedge[u]=i; pre[edges[i].v]=u; u=edges[i].v; } else { if(--num[h[u]]==0) break; curedge[u]=head[u]; for(x=n,i=head[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[edges[i].v]<x) x=h[edges[i].v]; h[u]=x+1;num[h[u]]++; if(u!=s) u=pre[u]; } } return ans; } int main() { while(scanf("%d%d",&m,&n)!=EOF) { int i,j,x,p,num; s=0;t=n+1; memset(head,-1,sizeof(head)); e=0; for(i=1;i<=m;i++) scanf("%d",&pig[i]); for(i=1;i<=m;i++) a[i][0]=0; for(i=1;i<=n;i++) { scanf("%d",&x); while(x--) scanf("%d",&p),a[p][++a[p][0]]=i; scanf("%d",&num); Add(i,t,num); } for(i=1;i<=m;i++) if(a[i][0]) Add(s,a[i][1],pig[i]); for(i=1;i<=m;i++) for(j=1;j<a[i][0];j++) Add(a[i][j],a[i][j+1],INF); printf("%d ",Maxflow(s,t,t)); } return 0; }