3438: 小M的作物
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1349 Solved: 578
[ Submit][ Status][ Discuss]
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
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。
样例解释A耕地种1,2,B耕地种3,收益4+2+3+2=11。
1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。
HINT
Source
具体看代码,话说最大闭合权子图什么的,表示没想到
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define INF 0x7fffffff
using namespace std;
const int N = 4005;
int last[N],S,T,n,m,h[N],q[N],cnt=1,cur[N],b[N],ans,MT,a[N],sum;
struct Edge{
int to,next,v;
}e[2100005];
void insert( int u, int v, int w ){
e[++cnt].to = v; e[cnt].next = last[u]; e[cnt].v = w; last[u] = cnt;
e[++cnt].to = u; e[cnt].next = last[v]; e[cnt].v = 0; last[v] = cnt;
}
bool bfs(){
memset(h,-1,sizeof(h));
int tail = 1, head = 0;
q[0] = 0; h[0] = 0;
while( tail != head ){
int now = q[head++];
for( int i = last[now]; i; i = e[i].next )
if( h[e[i].to] == -1 && e[i].v ){
h[e[i].to] = h[now] + 1;
q[tail++] = e[i].to;
}
}
return h[T] != -1;
}
int dfs( int x, int f ){
int w,used=0;
if( x == T ) return f;
for( int i = cur[x]; i; i = e[i].next )
if( h[e[i].to] == h[x] + 1 ){
w = dfs(e[i].to,min(e[i].v,f-used));
e[i].v -= w; e[i^1].v += w; used += w;
if( e[i].v ) cur[x] = i; if( f == used ) return f;
}
if( !used ) h[x] = -1;
return used;
}
void dinic(){
while( bfs() ){
for( int i = S; i <= T; i++ ) cur[i] = last[i];
ans += dfs(S,INF);
}
}
int main(){
scanf("%d", &n);
for( int i = 1; i <= n; i++ ) scanf("%d", &a[i]), sum += a[i];
for( int i = 1; i <= n; i++ ) scanf("%d", &b[i]), sum += b[i];
scanf("%d", &m);
S = 0; T = n+2*m+1;
for( int i = 1; i <= n; i++ ) insert(S,i,b[i]), insert(i,T,a[i]);
for( int i = 1; i <= m; i++ ){
int k,c1,c2;
scanf("%d%d%d", &k, &c1, &c2);
insert(S,n+i*2,c2);
insert(n+i*2-1,T,c1);
sum += c1+c2;
for( int j = 1,x; j <= k; j++ ){
scanf("%d", &x);
insert(x,n+i*2-1,INF);
insert(n+i*2,x,INF);
}
}
dinic();
printf("%d", sum - ans);
return 0;
}