建图跑最小割,加当前弧优化。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<algorithm> 6 #define N 3000 7 #define inf 0x3f3f3f3f 8 #define M 4000005 9 using namespace std; 10 int n,m; 11 int tot; 12 int head[N],nxt[M],ver[M],f[M]; 13 void add(int a,int b,int c) 14 { 15 tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;f[tot]=c; 16 tot++;nxt[tot]=head[b];head[b]=tot;ver[tot]=a;f[tot]=0; 17 } 18 int S,T; 19 int ch[N];int cur[N]; 20 int zeng(int a,int b) 21 { 22 if(a==T)return b; 23 int r=0; 24 for(int i=cur[a];i&&b>r;i=nxt[i]) 25 { 26 if(ch[ver[i]]==ch[a]+1&&f[i]) 27 { 28 int t=zeng(ver[i],min(b-r,f[i])); 29 r+=t;f[i]-=t;f[i^1]+=t; 30 if(f[i]>0)cur[a]=i; 31 } 32 } 33 if(!r)ch[a]=-1; 34 return r; 35 } 36 bool tell() 37 { 38 memset(ch,-1,sizeof(ch)); 39 ch[S]=0; 40 queue<int>q; 41 q.push(S); 42 while(!q.empty()) 43 { 44 int tmp=q.front();q.pop(); 45 for(int i=head[tmp];i;i=nxt[i]) 46 { 47 if(f[i]&&ch[ver[i]]==-1) 48 { 49 ch[ver[i]]=ch[tmp]+1; 50 q.push(ver[i]); 51 } 52 } 53 } 54 return ch[T]!=-1; 55 } 56 int dinic() 57 { 58 int r=0,t; 59 while(tell()) 60 { 61 for(int i=0;i<=T;i++)cur[i]=head[i]; 62 while(t=zeng(S,inf))r+=t; 63 } 64 return r; 65 } 66 int v[N]; 67 int ans; 68 int main() 69 { 70 tot=1; 71 scanf("%d%d",&n,&m);int t1,t2; 72 S=0;T=n+m+1; 73 for(int i=1;i<=n;i++) 74 { 75 int tmp; 76 scanf("%d%d",&v[i],&tmp);ans+=v[i]; 77 add(i+m,T,v[i]); 78 for(int j=1;j<=tmp;j++) 79 { 80 scanf("%d%d",&t1,&t2); 81 add(t1,i+m,t2); 82 } 83 } 84 for(int i=1;i<=m;i++) 85 { 86 scanf("%d",&t1); 87 add(S,i,t1); 88 } 89 printf("%d ",ans-dinic()); 90 return 0; 91 }