3438: 小M的作物

Description

小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

Sample Output

11
样例解释A耕地种1,2,B耕地种3,收益4+2+3+2=11。
1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。
 
最小割,难点在于怎么判断n个人同选的收益,只要新建两个额外点,一个向s连流量c1,一个向t连流量c2,这两个点与集合的所有点连,流量为无穷大,所以就变成了,这个集合要么都选,要么都不选,代价就是断几条边。。
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 #include<string>
 8 #include<map>
 9 #include<queue>
10 #include<vector>
11 #include<set>
12 #define inf 1000000000
13 #define maxn 100000+5
14 #define maxm 5000000+5
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
22 using namespace std;
23 int read(){
24     int x=0,f=1;char ch=getchar();
25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
27     return x*f;
28 }
29 int n,m,s,t,maxflow,tot=1,cnt,head[maxn],cur[maxn],h[maxn],q[maxn];
30 struct edge{
31     int go,next,w;
32 }e[maxm];
33 void insert(int u,int v,int w){
34     e[++tot]=(edge){v,head[u],w};head[u]=tot;
35     e[++tot]=(edge){u,head[v],0};head[v]=tot;
36 }
37 void ins(int u,int v,int w){
38     e[++tot]=(edge){v,head[u],w};head[u]=tot;
39     e[++tot]=(edge){u,head[v],w};head[v]=tot;
40 }
41 bool bfs(){
42     for0(i,t)h[i]=-1;
43     h[s]=0;q[1]=s;int l=0,r=1;
44     while(l!=r){
45         int x=q[++l];
46         for4(i,x)
47             if(e[i].w&&h[y]==-1)
48                 h[y]=h[x]+1,q[++r]=y;
49     }
50     return h[t]!=-1;
51 }
52 int dfs(int x,int f){
53     if(x==t)return f;
54     int tmp=0,used=0;
55     for4(i,x)
56         if(e[i].w&&h[y]==h[x]+1){
57             tmp=dfs(y,min(e[i].w,f-used));
58             e[i].w-=tmp;if(e[i].w)cur[x]=i;
59             e[i^1].w+=tmp;used+=tmp;
60             if(used==f)return f;
61         }
62     if(!used)h[x]=-1;
63     return used;
64 }
65 void dinic(){
66     maxflow=0;
67     while(bfs()){
68         for0(i,t)cur[i]=head[i];
69         maxflow+=dfs(s,inf);
70     }
71 }
72 int main(){
73     //freopen("input.txt","r",stdin);
74     //freopen("output.txt","w",stdout);
75     n=read();s=3005;t=s+1;int ans=0;
76     for1(i,n){
77         int x=read();ans+=x;
78         insert(s,i,x);
79     }
80     for1(i,n){
81         int x=read();ans+=x;
82         insert(i,t,x);
83     }
84     m=read();
85     for1(i,m){
86         int k=read(),c1=read(),c2=read();ans+=c1+c2;
87         insert(s,n+i,c1);insert(n*2+i,t,c2);
88         for1(j,k){
89             int x=read();
90             insert(n+i,x,inf);insert(x,n*2+i,inf);
91         }
92     }
93     dinic();
94     printf("%d\n",ans-maxflow);
95     return 0;
96 }
View Code

 

posted @ 2016-07-18 20:35  HTWX  阅读(289)  评论(0编辑  收藏  举报