BZOJ2127 happiness

很好的网络流题目啦,只不过有点烦,不过这下总算是完全掌握了Dinic的精髓。。。

首先考虑建图:

s --> A     权值为a[A] + sigma(他和四周都选全文科的高兴值) / 2

A --> t     权值为b[A] + sigma(他和四周都选全理科的高兴值) / 2

A <--> B  权值为(同时选文科的高兴值+同时选理科的高兴值) / 2

为了解决精度问题,边权先乘以二,最后结果再除以二即可。

但是不知道为什么是对的。。。在此Orz hzwer,要是没有他的程序我就完蛋了。。。

(p.s. 作死小剧场增强版   我数组d一开始刚好开了d[10002],然后t=10002,死活过不了,查了一下午,我也是醉了%>_<%)

  1 /**************************************************************
  2     Problem: 2127
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:2472 ms
  7     Memory:6900 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13
 14 #define rep(i, n) for (int (i) = 1; (i) <= (n); ++(i))
 15 #define REP for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j)
 16 using namespace std;
 17 const int inf = (int) 1e9;
 18
 19 struct edges{
 20     int next, to, f;
 21 } e[500000];
 22
 23 int n, m, ans, tot = 1, s, t;
 24 int first[10005], q[10005], d[10005];
 25 int w[101][101], a[101][101], b[101][101];
 26
 27 inline void add_edge(int x, int y, int z){
 28     e[++tot].next = first[x];
 29     first[x] = tot;
 30     e[tot].to = y;
 31     e[tot].f = z;
 32 }
 33
 34 inline void add_Edge(int x, int y, int z){
 35     add_edge(x, y, z);
 36     add_edge(y, x, 0);
 37 }
 38
 39 void add_Edges(int x, int y, int z){
 40     add_Edge(x, y, z);
 41     add_Edge(y, x, z);
 42 }
 43
 44 bool bfs(){
 45     memset(d, 0, sizeof(d));
 46     q[1] = s, d[s] = 1;
 47     int l = 0, r = 1, x, y;
 48     while (l < r){
 49         ++l;
 50         for (x = first[q[l]]; x; x = e[x].next){
 51             y = e[x].to;
 52             if (!d[y] && e[x].f)
 53                 q[++r] = y, d[y] = d[q[l]] + 1;
 54         }
 55     }
 56     return d[t];
 57 }
 58
 59 int dinic(int p, int limit){
 60     if (p == t || !limit) return limit;
 61     int x, y, tmp, rest = limit;
 62     for (x = first[p]; x; x = e[x].next){
 63         y = e[x].to;
 64         if (d[y] == d[p] + 1 && e[x].f && rest){
 65             tmp = dinic(y, min(rest, e[x].f));
 66             rest -= tmp;
 67             e[x].f -= tmp, e[x ^ 1].f += tmp;
 68             if (!rest) return limit;
 69         }
 70     }
 71     if (limit == rest) d[p] = 0;
 72     return limit - rest;
 73 }
 74
 75 int Dinic(){
 76     int res = 0, x;
 77     while (bfs())
 78         res += dinic(s, inf);
 79     return res;
 80 }
 81
 82 void make_graph(){
 83     int X;
 84     rep(i, n - 1) rep(j, m){
 85         scanf("%d", &X);
 86         ans += X, a[i][j] += X, a[i + 1][j] += X;
 87         add_Edges(w[i][j], w[i + 1][j], X);
 88     }
 89     rep(i, n - 1) rep(j, m){
 90         scanf("%d", &X);
 91         ans += X, b[i][j] += X, b[i + 1][j] += X;
 92         add_Edges(w[i][j], w[i + 1][j], X);
 93     }
 94     rep(i, n) rep(j, m - 1){
 95         scanf("%d", &X);
 96         ans += X, a[i][j] += X, a[i][j + 1] += X;
 97         add_Edges(w[i][j], w[i][j + 1], X);
 98     }
 99     rep(i, n) rep(j, m - 1){
100         scanf("%d", &X);
101         ans += X, b[i][j] += X, b[i][j + 1] += X;
102         add_Edges(w[i][j], w[i][j + 1], X);
103     }
104     s =  n * m + 1, t = s + 1;
105     REP{
106         add_Edge(s, w[i][j], a[i][j]);
107         add_Edge(w[i][j], t, b[i][j]);
108     }
109 }
110
111 int main(){
112     scanf("%d%d", &n, &m);
113     REP{
114         scanf("%d", a[i] + j);
115         ans += a[i][j], a[i][j] <<= 1;
116     }
117     REP{
118         scanf("%d", b[i] + j);
119         ans += b[i][j], b[i][j] <<= 1;
120     }
121     REP w[i][j] = (i - 1) * m + j;
122     make_graph();
123     printf("%d\n", ans - (Dinic() >> 1));
124     return 0;
125 }

时间: 2024-10-12 18:04:37

BZOJ2127 happiness的相关文章

YCB 的暑期计划

前言 YCB现在很弱(TAT) 暑假有一个月,赶快狂补一下. 大概的计划如下: 首先前期会以数据结构为主,毕竟代码能力太弱,涉及内容:线段树分治.二进制分组.KD-Tree. 等数据结构做到没有智商的时候加入一波数论,内容为 杜教筛.min_25筛. 然后中途小清新一下,做一些 组合博弈与构造题. 接着继续练代码能力,顺便学一些神奇的暴力:启发式合并.dsu on tree . 然后图论也忘的差不多了,就回过头去学点新东西,大概会有spfa判负环.0/1分数规划.差分约束. 估计这个时候也没有什

【bzoj2127】happiness 网络流最小割

题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. 输入 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值.第二个矩阵为n行m列 此矩阵的第i行

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

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

【BZOJ2127】happiness

Time Limit: 1000 ms   Memory Limit: 256 MB Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. Input 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵

CodeForces114E——Double Happiness(素数二次筛选)

Double Happiness On the math lesson a teacher asked each pupil to come up with his own lucky numbers. As a fan of number theory Peter chose prime numbers. Bob was more original. He said that number t is his lucky number, if it can be represented as:t

国家集训队2011 happiness

[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. [输入格式] 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学

bzoj2127:最小割

Orz问了师兄好久才懂了,看建图方式就想为什么会对应着三种情况,想流量代表的是什么,后来就画图,果然只有三种情况Orz...所以说要多画图多乱搞... s->(i,j),c=w.代表选理科: (i,j)->t,c=w,代表选文科: 新建k,s->k,c=w,k->(i,j),c=inf,k->(i,j+1),c=inf;代表同时选文或选理:同理. 出现的最小割只会有三种情况,一种是与s相连的都被割掉了,另一种是与t相连的都被割掉了,最后一种是s->k,s->(i,

数学(线性规划):UVAoj 10498 Happiness

Problem GHappiness! Input: standard inputOutput: standard outputTime Limit: 3 seconds Prof. Kaykobad has given Nasa the duty of buying some food for the ACM contestents. Nasa decided to buy n different items. He then asked each of the m contestents h

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> #i