bzoj 3438: 小M的作物
Description
背景
小M还是个特么喜欢玩MC的孩纸。。。
描述
小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小M找到了规则中共有m种作物组合,第i个组合中的作物共同种在A中可以获得c1i的额外收益,共同总在B中可以获得c2i的额外收益,所以,小M很快的算出了种植的最大收益,但是他想要考考你,你能回答他这个问题么?
Input
第一行包括一个整数n
第二行包括n个整数,表示ai
第三行包括n个整数,表示bi
第四行包括一个整数m
接下来m行,对于接下来的第i行:第一个整数ki,表示第i个作物组合中共有ki种作物,接下来两个整数c1i,c2i,接下来ki个整数,表示该组合中的作物编号。输出格式
Output
只有一行,包括一个整数,表示最大收益
Sample Input
3
4 2 1
2 3 2
1
2 3 2 1 2
4 2 1
2 3 2
1
2 3 2 1 2
Sample Output
11
样例解释
A耕地种1,2,B耕地种3,收益4+2+3+2=11。
数据范围与约定
对于100%的数据,1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。
样例解释
A耕地种1,2,B耕地种3,收益4+2+3+2=11。
数据范围与约定
对于100%的数据,1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。
网络流问题
新建源点S表示种在A地的作物,汇点T表示种在B地的作物,其他按照题意连边即可
#include<bits/stdc++.h> #define inf 0x7fffffff using namespace std; inline int read(){ int s=0;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar()); for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0'; return s; } int n,m; struct node{ int to,next; int cap,flow; }G[2000010]; int tot=1,h[10010]; int vis[10010]; int S,T,cnt; int sum; void add(int x,int y,int z){ tot++;G[tot].to=y;G[tot].next=h[x];G[tot].cap=z;h[x]=tot; } void ins(int x,int y,int z){ add(x,y,z);add(y,x,0); } void init(){ n=read();S=0,T=n+1;cnt=n+1; for(int i=1;i<=n;++i){ int x=read();ins(S,i,x);sum+=x; } for(int i=1;i<=n;++i){ int x=read();ins(i,T,x);sum+=x; } m=read(); for(int i=1;i<=m;++i){ int k=read(),x=read(),y=read(); ++cnt;ins(S,cnt,x);ins(cnt+1,T,y);sum+=x+y; for(int j=1;j<=k;++j){ int z=read();ins(cnt,z,inf);ins(z,cnt+1,inf); } ++cnt; } } int F(int i){ return G[i].cap-G[i].flow; } bool bfs(){ queue<int>Q;Q.push(S); memset(vis,0,sizeof(vis));vis[S]=1; while(!Q.empty()){ int u=Q.front();Q.pop(); for(int i=h[u];i;i=G[i].next){ int v=G[i].to; if(vis[v]||F(i)<=0)continue; vis[v]=vis[u]+1; Q.push(v); if(v==T)return 1; } }return 0; } int dfs(int u,int w){ if(u==T||w==0)return w; int flow=0; for(int i=h[u];i;i=G[i].next){ int v=G[i].to; if(vis[v]!=vis[u]+1||F(i)<=0)continue; if(int t=dfs(v,min(w,F(i)))){ G[i].flow+=t;G[i^1].flow-=t; flow+=t;w-=t; if(!w)break; } } if(!flow)vis[u]=0; return flow; } void dinic(){ int f=0; while(bfs()){ f+=dfs(S,inf); }cout<<sum-f<<endl; } int main(){ init(); dinic(); return 0; }