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

orz出题人云神...

放上官方题解... 转成最小割然后建图跑最大流就行了...

------------------------------------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#define rep(i, n) for(int i = 0; i < n; i++)

#define clr(x, c) memset(x, c, sizeof(x))

using namespace std;

const int maxn = 3010, inf = int(2e9);

struct edge {

int to, cap;

edge*next, *rev;

} E[4008000], *pt = E, *head[maxn];

inline void add(int u, int v, int w) {

pt->to = v, pt->cap = w;

pt->next = head[u];

head[u] = pt++;

}

inline void add_edge(int u, int v, int w) {

add(u, v, w), add(v, u, 0);

head[u]->rev = head[v];

head[v]->rev = head[u];

}

edge*p[maxn], *cur[maxn];

int h[maxn], cnt[maxn], S, T, N;

int maxFlow() {

clr(h, 0), clr(cnt, 0), cnt[S] = N;

rep(i, N) cur[i] = head[i];

edge*e;

int flow = 0;

for(int x = S, A = inf; h[S] < N; ) {

for(e = head[x]; e; e = e->next)

if(h[e->to] + 1 == h[x] && e->cap) break;

if(e) {

cur[x] = p[e->to] = e;

A = min(A, e->cap);

x = e->to;

if(x == T) {

for(; x != S; x = p[x]->rev->to) {

p[x]->cap -= A;

p[x]->rev->cap += A;

}

flow += A;

A = inf;

}

} else {

if(!--cnt[h[x]]) break;

h[x] = N;

for(e = head[x]; e; e = e->next) if(h[e->to] + 1 < h[x] && e->cap) {

h[x] = h[e->to] + 1;

cur[x] = e;

}

++cnt[h[x]];

if(x != S) x = p[x]->rev->to;

}

}

return flow;

}

int main() {

freopen("test.in", "r", stdin);

int ans = 0, n;

clr(head, 0);

cin >> n;

S = 0, T = n + 1, N = T + 1;

rep(i, n) {

int v;

scanf("%d", &v);

ans += v;

add_edge(S, i + 1, v);

}

rep(i, n) {

int v;

scanf("%d", &v);

ans += v;

add_edge(i + 1, T, v);

}

cin >> n;

while(n--) {

int k, c1, c2, t;

scanf("%d%d%d", &k, &c1, &c2);

ans += c1 + c2;

int u = N++, v = N++;

add_edge(S, u, c1), add_edge(v, T, c2);

while(k--) {

scanf("%d", &t);

add_edge(u, t, inf), add_edge(t, v, inf);

}

}

cout << ans - maxFlow() << "\n";

return 0;

}

------------------------------------------------------------------------------------------

3438: 小M的作物

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 474  Solved: 226
[Submit][Status][Discuss]

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
421
232
1
23212

Sample Output

11

样例解释

A耕地种1,2,B耕地种3,收益4+2+3+2=11。

数据范围与约定

对于100%的数据,1<=k< n<= 1000,0

HINT

Source

Kpmcup#0 By Greens

时间: 2024-11-01 01:22:55

BZOJ 3438: 小M的作物( 最小割 )的相关文章

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

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

【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]

BZOJ 1266 上学路线route(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1266 题意:给出一个无向图,每条边有长度和代价.求出1到n的最短路.之后删掉一些边使得1到n的最短路变大?在此情况下使得删掉边的代价之和最小. 思路:首先求出每个点到1和n的最短路.之后可以确定每条边是否为关键边(就是最短路上的边).将关键边建立网络流图,求最小割即可. struct node { int v,cap,next; }; node edges[N]; int head[N

BZOJ 1976 能量魔方 Cube(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1976 题意:给出一个n*n*n的立方体.每个小单位为字母P或者字母N.相邻两个小单位字母不同则总价值加1.现在有些小单位的字母已经确定,合理安排其他小单位的字母使得总价值最大? 思路:显然,若所有小单位都未确定,则进 行黑白染色即PN相间的安排时价值最大.基于这样的考虑,我们将所有小单位分成黑白两种颜色,设为A和B.显然同一种颜色之间是不会相邻的.设S集合为A 集合中的P(就是已经给出

BZOJ 2132 圈地计划(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2132 题意:n*m的格子染色黑白,对于格子(i,j)染黑色则价值为A[i][j],白色为B[i][j].若一个格子四周不同颜色的有x个,则额外的价值为x*C[i][j].求最大价值. 思路:将格子黑白染色分成两个集合X和Y.S集合为X中的A和Y中的B,T为X中的B和Y中的A.相邻的连边为两个格子的C值之和.总权值减去最小割即是答案. struct node { int v,cap,ne

[BZOJ 3774] 最优选择 【最小割】

题目链接:BZOJ - 3774 题目分析 此题与“文理分科”那道题目有些类似.都是使用最小割来求解,先加上可能获得的权值,在减掉必须舍弃的权值(最小割). 文理分科是规定每个人和 S 连就是选文,和 T 连就是选理.然后如果一个人和相邻的人都全文就会获得一个权值,那么我们就为这个权值建一个点,让这个点与必须同时选文的5个人连 INF 边.这样只要这 5 个人中有一个人选了理,就必须舍弃这个权值了. 再回到这道题目,这道题获得权值的条件是这个点被控制或这个点相邻的 4 个点都被控制. 这个“或”

BZOJ 2007 NOI 2010 海拔 平面图最小割-&gt;最短路SPFA+pq

题目大意:给出一个城市各个道路的双向流量,城市的左上角的高度是0,城市的右下角的高度是1,若人流升高海拔就会消耗体力,问最小需要消耗多少体力. 思路:这道题才是真正的让我见识到了algorithm中的heap的强大. 分析这道题可以发现,一定会有一条分界线,这个分界线左边高度都为0,右边高度都是1,然后找到这条分界点就可以了.明显的最小割.但是数据量巨大,直接跑最大流会T,又是平面图,建立对偶图然后跑最短路,SPFA+pq在BZOJ上可以很快,如果有的OJ卡STL的话可以考虑SPFA+Heap,

BZOJ 1266 上学路线(最短路+最小割)

给出n个点的无向图,每条边有两个属性,边权和代价. 第一问求1-n的最短路.第二问求用最小的代价删边使得最短路的距离变大. 对于第二问.显然该删除的是出现在最短路径上的边.如果我们将图用最短路跑一遍预处理出所有最短路径. 然后我们要删除的边集一定是这个图的一个割.否则最短路径不会增加.即求此图的最小割. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream>