HDU 3820 Golden Eggs (最小割)
来源:互联网 发布:js图片懒加载 编辑:程序博客网 时间:2024/05/23 19:15
Golden Eggs
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 285 Accepted Submission(s): 161
Problem Description
There is a grid with N rows and M columns. In each cell you can choose to put a golden or silver egg in it, or just leave it empty. If you put an egg in the cell, you will get some points which depends on the color of the egg. But for every pair of adjacent eggs with the same color, you lose G points if there are golden and lose S points otherwise. Two eggs are adjacent if and only if there are in the two cells which share an edge. Try to make your points as high as possible.
Input
The first line contains an integer T indicating the number of test cases.
There are four integers N, M, G and S in the first line of each test case. Then 2*N lines follows, each line contains M integers. The j-th integer of the i-th line Aij indicates the points you will get if there is a golden egg in the cell(i,j). The j-th integer of the (i+N)-th line Bij indicates the points you will get if there is a silver egg in the cell(i,j).
Technical Specification
1. 1 <= T <= 20
2. 1 <= N,M <= 50
3. 1 <= G,S <= 10000
4. 1 <= Aij,Bij <= 10000
Output
For each test case, output the case number first and then output the highest points in a line.
Sample Input
2
2 2 100 100
1 1
5 1
1 4
1 1
1 4 85 95
100 100 10 10
10 10 100 100
Sample Output
Case 1: 9
Case 2: 225
这道题是HDU 1565,1569,3657的加强版。不过只要做过前面那几道,就会发现其实是“换汤不换药”的题。加强的地方在于,每一个方格的数不是固定的了,它可以是金蛋也可以是银蛋。那么对于任意一点,要放金蛋还是银蛋呢?其实这就是最小割的模型,二者选一个小的,最后结果是总权值-最小割。所以处理方法是拆点,对于每一个位置,拆出一个点,一个表示放的是金蛋,拆出来的表示放银蛋,对于这两个点连边,最后结果不就是求出二者中小的那个吗?所以,把横纵坐标之和为偶数的点表示放了金蛋,与源点连接,权值为放金蛋的值,然后把这些点拆开,拆出来的放银蛋,与汇点连权值为放银蛋的值。最后这些点对应连一条权值为无穷大的边。然后,把横纵坐标之和为奇数的点表示放了银蛋,也与源点连边,权值为放银蛋的值,拆出来的点和汇点连接权值为放金蛋的边,对应的点也连一条无穷大的边。最后把横纵坐标之和为偶数的且放金蛋的点与横纵坐标之和为奇数的放金蛋的相连,权值为G,横纵坐标之和为奇数的且放银蛋的点和横纵坐标之和为偶数的放银蛋的点相连,权值为S。
既(1)横纵坐标之和为偶数的点的集合为d,把他们与源点连金蛋的值,拆点为d',把他们与汇点连银蛋的值,再d-d'无穷;
(2)横纵坐标之和为奇数的点的集合为s,把他们与源点连银蛋的值,拆点为s',把他们与汇点连金蛋的值,再s-s'无穷;
(3)把d-s'连权值为G的边,s-d'连权值为S的边。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define SIZE 5005#define inf 0xfffffffusing namespace std;struct node{ int to,val,next;}edge[SIZE*15];int N,M,G,S,sc,sk,pt,sum;int head[SIZE],idx;int gap[SIZE],dis[SIZE];int gold[64][64],silver[64][64];void addnode(int from,int to,int val){ edge[idx].to = to; edge[idx].val = val; edge[idx].next = head[from]; head[from] = idx ++; edge[idx].to = from; edge[idx].val = 0; edge[idx].next= head[to]; head[to] = idx ++;}int dfs(int cur,int cval){ if(cur == sk) return cval; int mindis = pt - 1, tval = cval; for(int i=head[cur]; i!=-1; i=edge[i].next) { int to = edge[i].to; if(edge[i].val > 0) { if(dis[to] + 1 == dis[cur]) { int val = dfs(to,min(edge[i].val,tval)); tval -= val; edge[i].val -= val; edge[i^1].val += val; if(dis[sc] >= pt) return cval - tval; if(!tval) break; } if(mindis > dis[to]) mindis = dis[to]; } } if(cval == tval) { --gap[dis[cur]]; if(!gap[dis[cur]]) dis[sc] = pt; dis[cur] = mindis + 1; ++gap[dis[cur]]; } return cval - tval;}void sap(){ memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); int ret = 0; gap[sc] = pt; while(dis[sc] < pt) ret += dfs(sc,inf); printf("%d\n",sum-ret);}void read(){ sum = 0; for(int i=1; i<=N; i++) { for(int j=1; j<=M; j++) { scanf("%d",&gold[i][j]); sum += gold[i][j]; } } for(int i=1; i<=N; i++) { for(int j=1; j<=M; j++) { scanf("%d",&silver[i][j]); sum += silver[i][j]; } } sc = 0, sk = N*M*2+1, pt = sk+1; idx = 0; memset(head,-1,sizeof(head)); int pos; for(int i=1; i<=N; i++) { for(int j=1; j<=M; j++) { pos = (i-1)*M+j; if((i+j)%2) { addnode(sc,pos,silver[i][j]); addnode(pos,pos+N*M,inf); addnode(pos+N*M,sk,gold[i][j]); if(i - 1 >= 1) addnode(pos,pos+N*M-M,S); if(i + 1 <= N) addnode(pos,pos+N*M+M,S); if(j - 1 >= 1) addnode(pos,pos+N*M-1,S); if(j + 1 <= M) addnode(pos,pos+N*M+1,S); } else { addnode(sc,pos,gold[i][j]); addnode(pos,pos+N*M,inf); addnode(pos+N*M,sk,silver[i][j]); if(i - 1 >= 1) addnode(pos,pos+N*M-M,G); if(i + 1 <= N) addnode(pos,pos+N*M+M,G); if(j - 1 >= 1) addnode(pos,pos+N*M-1,G); if(j + 1 <= M) addnode(pos,pos+N*M+1,G); } } }}int main(){ int Case; scanf("%d",&Case); for(int ca = 1; ca <= Case; ca++) { scanf("%d%d%d%d",&N,&M,&G,&S); read(); printf("Case %d: ",ca); sap(); } return 0;}
- HDU 3820 Golden Eggs (最小割)
- HDU 3820 Golden Eggs (最小割)
- hdu 3820 Golden Eggs 最小割
- 【HDU】3820 Golden Eggs 最小割
- hdu 3820 Golden Eggs 最小割
- HDU 3820 Golden Eggs( 最小割 奇特建图)经典
- hdu 3820 Golden Eggs(最小割+SAP)
- 【hdu3820】【最小割】Golden Eggs
- hdu 3820 Golden Eggs(最小割,最大点权独立集+拆点)
- hdu 3820 Golden Eggs【最大流Dinic-------最小割】好题
- hdoj 3820 Golden Eggs 【最小割+拆点】
- hdu3280 Golden Eggs(网络流最小割)
- hdu3820 Golden Eggs(最小割)
- HDOJ 3820 - Golden Eggs 构图最小割(类似二分图的最大独立点权集)
- hdoj 3820 Golden Eggs 【双二分图构造最小割模型】
- HDU 3820 Golden Eggs 方格取数加强版
- HDU 3820 Golden Eggs(最大独立集)
- hdu 3820 最小割
- XMPP简单压测
- 交通灯管理系统——向张孝祥老师学习
- Android系统定制之源码完美下载
- Win7文件夹拒接访问解决方案
- 解决Android Debug certificate expired on ****
- HDU 3820 Golden Eggs (最小割)
- hdoj_1232畅通工程 && hdoj_1272小希的迷宫 && hdoj_1213How Many Tables && Is It A Tree?
- linux下qq客户端
- Windows 7“文件无法显示缩略图”?检查系统盘可用空间看看
- #ifdef的用法
- android开发环境搭建
- MyEclipse/Eclipse 创建模板代码/文件读写代码块
- C# 3.0新语言特性和改进
- Uva 10369 - Arctic Network//kruskal