3438: 小M的作物[最小割]

3438: 小M的作物

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1073  Solved: 465
[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

Sample Output

11
样例解释A耕地种1,2,B耕地种3,收益4+2+3+2=11。
1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。

HINT

Source

建图:

  • 把各种子看作点,源点向各点i连容量ai的边,各点i向汇点连容量bi的边。
  • 也把组合看作点,并拆成两点x,x‘,源点向x连c1i的边,x‘向汇点连c2i的边。
  • 对于组合x和种子i之间的关系,x向i建容量INF的边,i向x‘连容量INF的边。

ans:Σai+Σbi+Σc1i+Σc2i-最小割

#include<cstdio>
#include<iostream>
using namespace std;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int n,m,S,T,ans,a[N],b[N],dis[N],head[N],q[N*10];
struct node{
    int v,next,cap;
}e[N*20];int tot=1;
void add(int x,int y,int z){
    e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
    e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;
}
bool bfs(){
    for(int i=S;i<=T;i++) dis[i]=-1;
    int h=0,t=1;dis[S]=0;q[t]=S;
    while(h!=t){
        int x=q[++h];
        for(int i=head[x],v;i;i=e[i].next){
            if(e[i].cap&&dis[v=e[i].v]==-1){
                dis[v]=dis[x]+1;
                if(v==T) return 1;
                q[++t]=v;
            }
        }
    }
    return 0;
}
int dfs(int x,int f){
    if(x==T||!f) return f;
    int used=0,t;
    for(int i=head[x],v;i;i=e[i].next){
        if(e[i].cap&&dis[v=e[i].v]==dis[x]+1){
            t=dfs(v,min(f,e[i].cap));
            e[i].cap-=t;e[i^1].cap+=t;
            used+=t;f-=t;
            if(!f) return used;
        }
    }
    if(!used) dis[x]=-1;
    return used;
}
void dinic(){
    while(bfs()) ans-=dfs(S,inf);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),ans+=a[i];
    for(int i=1;i<=n;i++) scanf("%d",&b[i]),ans+=b[i];
    scanf("%d",&m);T=n+m+m+1;
    for(int i=1;i<=n;i++){
        add(S,i,a[i]),add(i,T,b[i]);
    }
    for(int i=1,k,x,y;i<=m;i++){
        scanf("%d%d%d",&k,&x,&y);ans+=x+y;
        add(S,i+n,x);add(i+n+m,T,y);
        while(k--){
            scanf("%d",&x);
            add(i+n,x,inf);
            add(x,i+n+m,inf);
        }
    }
    dinic();
    printf("%d",ans);
    return 0;
} 
时间: 2024-08-05 15:09:33

3438: 小M的作物[最小割]的相关文章

BZOJ 3438: 小M的作物( 最小割 )

orz出题人云神... 放上官方题解... 转成最小割然后建图跑最大流就行了... ------------------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep(i, n) for(in

【BZOJ-3438】小M的作物 最小割 + 最大权闭合图

3438: 小M的作物 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 825  Solved: 368[Submit][Status][Discuss] Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就

[P1361] 小M的作物 - 最小割

没想到今天早上的第一题网络流就血了这么多发 从经典的二选一问题上魔改 仍然考虑最小割 #include <bits/stdc++.h> using namespace std; #define int long long const int N = 163840, MAXN = 2602144; #define reset(x) memset(x,0,sizeof x) namespace solver { struct graph { int n,m,M,S,T,head[N],cur[N]

HDU 6214 Smallest Minimum Cut 最小割,权值编码

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6214 题意:求边数最小的割. 解法: 建边的时候每条边权 w = w * (E + 1) + 1; 这样得到最大流 maxflow / (E + 1) ,最少割边数 maxflow % (E + 1) 道理很简单,如果原先两类割边都是最小割,那么求出的最大流相等 但边权变换后只有边数小的才是最小割了 乘(E+1)是为了保证边数叠加后依然是余数,不至于影响求最小割的结果 因为假设最小割=k,那么现在新

hiho一下 第119周 #1398 : 网络流五&#183;最大权闭合子图 【最小割-最大流--Ford-Fulkerson 与 Dinic 算法】

#1398 : 网络流五·最大权闭合子图 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编号1..M),邀请编号为i的同学来参加班级建设活动需要消耗b[i]的活跃值. 每项活动都需要某些学生在场才能够进行,若其中有任意一个学生没有被邀请,这项活动就没有办法进行. 班级建设的活

HDU 3987 Harry Potter and the Forbidden Forest(最小割中的最少割边)经典

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1791    Accepted Submission(s): 596 Problem Description Harry Potter notices some Death Eaters try to slip

hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割

view code//hdu 3987 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; typedef long long ll; const ll INF = 1LL<<59; const ll E = 100001; const int N = 10

BZOJ3438 小M的作物(最小割)

题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小M找到了规则中共有m种作物组

【bzoj3438】小M的作物 网络流最小割

原文地址:http://www.cnblogs.com/GXZlegend/p/6801522.html 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小M找到了规则中共有m种作物组合,第i个组合中的作物共同种在A中