BZOJ 2127: happiness( 最小割 )

最小割..

S连每个人(容量:选择理科的愉悦);每个人连T(容量:选择理科的愉悦) .

对于每一组(x, y, w)x和y同选理增加的愉悦w,新建节点V,V连x(INF),V连y(INF), S连V(w)

对于每一组(x, y, w)x和y同选文增加的愉悦w,新建节点V,x连V(INF),y连V(INF), V连T(w)

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

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cctype>

using namespace std;

const int maxn = 60000;

const int INF = 100000000;

int read() {

char c = getchar();

int ret = 0;

for(; !isdigit(c); c = getchar());

for(; isdigit(c); c = getchar()) ret = ret * 10 + c - ‘0‘;

return ret;

}

int N, M, S, T, V, tot = 0;

struct edge {

int to, cap;

edge *next, *rev;

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

void Add(int u, int v, int w) {

pt->to = v; pt->cap = w; pt->next = head[u]; head[u] = pt++;

}

void AddEdge(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];

int maxFlow() {

memset(cnt, 0, sizeof cnt);

memset(h, 0, sizeof h);

for(int i = 0; i < V; i++)

cur[i] = head[i];

cnt[0] = V;

int Flow = 0;

edge* e;

for(int x = S, A = INF; h[S] < V; ) {

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

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

if(e) {

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

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

if((x = e->to) == 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] = V;

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;

}

void Init() {

scanf("%d%d", &N, &M);

S = N * M; T = S + 1;

for(int i = 0; i < N; i++)

for(int j = 0; j < M; j++) {

int v = read();

tot += v;

AddEdge(i * M + j, T, v);

}

for(int i = 0; i < N; i++)

for(int j = 0; j < M; j++) {

int v = read();

tot += v;

AddEdge(S, i * M + j, v);

}

V = T;

for(int i = 1; i < N; i++)

for(int j = 0; j < M; j++) {

int v = read();

tot += v;

AddEdge(++V, T, v);

AddEdge(i * M + j, V, INF);

AddEdge((i - 1) * M + j, V, INF);

}

for(int i = 1; i < N; i++)

for(int j = 0; j < M; j++) {

int v = read();

tot += v;

AddEdge(S, ++V, v);

AddEdge(V, i * M + j, INF);

AddEdge(V, (i - 1) * M + j, INF);

}

for(int i = 0; i < N; i++)

for(int j = 1; j < M; j++) {

int v = read();

tot += v;

AddEdge(++V, T, v);

AddEdge(i * M + j, V, INF);

AddEdge(i * M + j - 1, V, INF);

}

for(int i = 0; i < N; i++)

for(int j = 1; j < M; j++) {

int v = read();

tot += v;

AddEdge(S, ++V, v);

AddEdge(V, i * M + j, INF);

AddEdge(V, i * M + j - 1, INF);

}

++V;

}

int main() {

Init();

printf("%d\n", tot - maxFlow());

return 0;

}

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

2127: happiness

Time Limit: 51 Sec  Memory Limit: 259 MB
Submit: 1119  Solved: 530
[Submit][Status][Discuss]

Description

高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

Input

第一行两个正整数n,m。接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。

Output

输出一个整数,表示喜悦值总和的最大值

Sample Input

1 2
1 1
100 110
1
1000

Sample Output

1210
【样例说明】
两人都选理,则获得100+110+1000的喜悦值。
【数据规模】
对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数

HINT

Source

时间: 2024-10-06 08:23:42

BZOJ 2127: happiness( 最小割 )的相关文章

BZOJ 2127: happiness(最小割解决集合划分)

Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2350  Solved: 1138[Submit][Status][Discuss] Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的

[BZOJ 2127] happiness 【最小割】

题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建图.首先使用最小割,就是先加上所有可能获得的权值,再减去最小割(即不能获得的权值). 如果一个人学理,就要割掉与 S 相连的边,那么就是要割掉学文的收益.于是,对于每个点,从 S 向它连边,权值为它学文的收益. 同理,对于每个点,从它向 T 连边,权值为它学理的收益. 对于两个相邻的人,他们有同时学

BZOJ 2561: 最小生成树(最小割)

U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------------------------- #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<que

bzoj 2127: happiness

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define M 100009 5 #define inf 2139062143 6 using namespace std; 7 int n,m,a[102][102],b[102][102],c[102][102],tot,cnt=1,T,ans,head[M],d[M],q[2*M],next[10*M],u[10*M],v[10*M];

【BZOJ2127】happiness 最小割 自己YY出来的建图、

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42609669 其实我就是觉得原创的访问量比未授权盗版多有点不爽233... 那个一看就觉得不是费用流就是最小割. 想想就确定最小割了. 考虑到一个人,文理不可兼得,不妨先建点,然后向源点(文科),汇点(理科)连边,流量(也就是割)是对应喜悦值.(这里的想法是先建个差不多的,有漏洞再拆点啊,建辅助点啊什么的) 然后再考虑一对朋友之间的共文理喜悦值: 如果都选文,那么需要割掉双方都选理的喜悦

BZOJ 2229 ZJOI2011 最小割 最小割+分治 400AC达成&amp;&amp;2000Submission达成

题目大意:给定一个图,多次询问有多少个点对之间的最小割小于等于某个值 最小割分治- - 首先朴素的想法是做O(n^2)遍网络流 但是这样显然是过不去的 根据一些结论,最小割最多有n-1个,这n-1个最小割构成一个最小割树 别问我为什么- - 因此我们分治寻找这n-1个最小割 每层分治,先任选两个点作为源汇做一遍最小割 然后找出S集和T集,对所有S集的点和T集的点构成的点对用本次得到的最小割更新一遍 注意更新的是全部S集和全部T集,不只是本次分治内部的S集和T集 然后将本次分治的点分成S集和T集,

bzoj 2127 happiness【网络流dinic】

参考:https://www.cnblogs.com/chenyushuo/p/5144957.html 不得不说这个建图方法真是非常妙啊 假设S点选理,T点选文,a[i][j]为(i,j)选文收益,b[i][j]为(i,j)选理收益,c[i][j]为同时选文收益,d[i][j]为同时选文收益. 那么对于每个点x=(i+1)*m+j,我们连接 \[ c[s,x]=b[i][j] \] \[ c[x,t]=a[i][j] \] 对于有利益相关的x,y两点,连接 \[ c[s,x]=d[i][j]/

bzoj——2127: happiness

2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2570  Solved: 1242[Submit][Status][Discuss] Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老

[BZOJ 2127]happiness(最小割)

Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. Solution 和文理分科那道一样啊…1A #include<iostream> #include<cstdlib> #include<cstd