HDU 3820 Golden Eggs (SAP | Dinic)
Golden Eggs
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 304 Accepted Submission(s): 172
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
2 2 100 100
1 1
5 1
1 4
1 1
1 4 85 95
100 100 10 10
10 10 100 100
Case 2: 225
还是SAP快:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int VM=;
const int EM=;
const int INF=0x3f3f3f3f; struct Edge{
int to,nxt;
int cap;
}edge[EM<<]; int n,m,G,S,cnt,head[VM],src,des,map1[][],map2[][];
int dep[VM],gap[VM],cur[VM],aug[VM],pre[VM]; void addedge(int cu,int cv,int cw){
edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].nxt=head[cu];
head[cu]=cnt++;
edge[cnt].to=cu; edge[cnt].cap=; edge[cnt].nxt=head[cv];
head[cv]=cnt++;
} int SAP(int n){
int max_flow=,u=src,v;
int id,mindep;
aug[src]=INF;
pre[src]=-;
memset(dep,,sizeof(dep));
memset(gap,,sizeof(gap));
gap[]=n;
for(int i=;i<=n;i++)
cur[i]=head[i]; // 初始化当前弧为第一条弧
while(dep[src]<n){
int flag=;
if(u==des){
max_flow+=aug[des];
for(v=pre[des];v!=-;v=pre[v]){ // 路径回溯更新残留网络
id=cur[v];
edge[id].cap-=aug[des];
edge[id^].cap+=aug[des];
aug[v]-=aug[des]; // 修改可增广量,以后会用到
if(edge[id].cap==) // 不回退到源点,仅回退到容量为0的弧的弧尾
u=v;
}
}
for(int i=cur[u];i!=-;i=edge[i].nxt){
v=edge[i].to; // 从当前弧开始查找允许弧
if(edge[i].cap> && dep[u]==dep[v]+){ // 找到允许弧
flag=;
pre[v]=u;
cur[u]=i;
aug[v]=min(aug[u],edge[i].cap);
u=v;
break;
}
}
if(!flag){
if(--gap[dep[u]]==) // gap优化,层次树出现断层则结束算法
break;
mindep=n;
cur[u]=head[u];
for(int i=head[u];i!=-;i=edge[i].nxt){
v=edge[i].to;
if(edge[i].cap> && dep[v]<mindep){
mindep=dep[v];
cur[u]=i; // 修改标号的同时修改当前弧
}
}
dep[u]=mindep+;
gap[dep[u]]++;
if(u!=src) // 回溯继续寻找允许弧
u=pre[u];
}
}
return max_flow;
} int main(){ //freopen("input.txt","r",stdin); int t,cases=;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&m,&G,&S);
cnt=;
memset(head,-,sizeof(head));
src=; des=n*m*+;
int sum=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
scanf("%d",&map1[i][j]);
sum+=map1[i][j];
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
scanf("%d",&map2[i][j]);
sum+=map2[i][j];
}
int tmp;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
tmp=(i-)*m+j;
if((i+j)%==){
addedge(src,tmp,map1[i][j]);
addedge(tmp,tmp+n*m,INF);
addedge(tmp+n*m,des,map2[i][j]); if(i>) addedge(tmp,tmp-m+n*m,G);
if(i<n) addedge(tmp,tmp+m+n*m,G);
if(j>) addedge(tmp,tmp-+n*m,G);
if(j<m) addedge(tmp,tmp++n*m,G); }else{
addedge(src,tmp,map2[i][j]);
addedge(tmp,tmp+n*m,INF);
addedge(tmp+n*m,des,map1[i][j]); if(i>) addedge(tmp,tmp-m+n*m,S);
if(i<n) addedge(tmp,tmp+m+n*m,S);
if(j>) addedge(tmp,tmp-+n*m,S);
if(j<m) addedge(tmp,tmp++n*m,S);
}
}
}
printf("Case %d: %d\n",++cases,sum-SAP(des+));
}
return ;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int VM=;
const int EM=;
const int INF=0x3f3f3f3f; struct Edge{
int to,nxt;
int cap;
}edge[EM<<]; int n,m,G,S,cnt,head[VM],src,des;
int map1[][],map2[][],dep[VM]; //dep[i]表示当前点到起点src的层数 void addedge(int cu,int cv,int cw){
edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].nxt=head[cu];
head[cu]=cnt++;
edge[cnt].to=cu; edge[cnt].cap=; edge[cnt].nxt=head[cv];
head[cv]=cnt++;
} int BFS(){ // 重新建图(按层数建图)
queue<int> q;
while(!q.empty())
q.pop();
memset(dep,-,sizeof(dep));
dep[src]=;
q.push(src);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(edge[i].cap> && dep[v]==-){ // 如果可以到达且还没有访问
dep[v]=dep[u]+;
q.push(v);
}
}
}
return dep[des]!=-;
} int DFS(int u,int minx){ // 查找路径上的最小的流量
if(u==des)
return minx;
int tmp;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(edge[i].cap> && dep[v]==dep[u]+ && (tmp=DFS(v,min(minx,edge[i].cap)))){
edge[i].cap-=tmp; //正向减少
edge[i^].cap+=tmp; //反向增加
return tmp;
}
}
dep[u]=-; //这一句作用无穷大,不在TLE。。。。。。。。。。。
return ;
} int Dinic(){
int ans=,tmp;
while(BFS()){
while(){
tmp=DFS(src,INF);
if(tmp==)
break;
ans+=tmp;
}
}
return ans;
} int main(){ //freopen("input.txt","r",stdin); int t,cases=;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&m,&G,&S);
cnt=;
memset(head,-,sizeof(head));
src=; des=n*m*+;
int sum=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
scanf("%d",&map1[i][j]);
sum+=map1[i][j];
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
scanf("%d",&map2[i][j]);
sum+=map2[i][j];
}
int tmp;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
tmp=(i-)*m+j;
if((i+j)%==){
addedge(src,tmp,map1[i][j]);
addedge(tmp,tmp+n*m,INF);
addedge(tmp+n*m,des,map2[i][j]);
//
if(i!=)addedge(tmp,tmp-m+n*m,G);
if(i!=n)addedge(tmp,tmp+m+n*m,G);
if(j!=)addedge(tmp,tmp-+n*m,G);
if(j!=m)addedge(tmp,tmp++n*m,G);
//
}
else{
addedge(src,tmp,map2[i][j]);
addedge(tmp,tmp+n*m,INF);
addedge(tmp+n*m,des,map1[i][j]);
if(i!=)addedge(tmp,tmp-m+n*m,S);
if(i!=n)addedge(tmp,tmp+m+n*m,S);
if(j!=)addedge(tmp,tmp-+n*m,S);
if(j!=m)addedge(tmp,tmp++n*m,S);
}
}
}
printf("Case %d: %d\n",++cases,sum-Dinic());
}
return ;
}
HDU 3820 Golden Eggs (SAP | Dinic)的更多相关文章
- HDU 3820 Golden Eggs( 最小割 奇特建图)经典
Golden Eggs Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 3820 Golden Eggs
http://acm.hdu.edu.cn/showproblem.php?pid=3820 题意:n*m的格子,每个格子放金蛋或银蛋,每个格子的金蛋和银蛋都有一个对应的点权,如果有两个金蛋相连,则需 ...
- HDU3820 Golden Eggs(最小割)
题目大概说给一个n*m的格子,每个格子放金蛋或银蛋都会得到不同的价值,当然也可以不放,不过如果存在相邻的两个格子都是金蛋会损失价值g,都是银则损失s.问能得到的最大价值. 有点像二者选一的最小割模型, ...
- HDU 5860 Death Sequence(死亡序列)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...
- HDU 5877 Weak Pair(弱点对)
HDU 5877 Weak Pair(弱点对) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Jav ...
- HDU 5813 Elegant Construction(优雅建造)
HDU 5813 Elegant Construction(优雅建造) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65 ...
- HDU 5818 Joint Stacks(联合栈)
HDU 5818 Joint Stacks(联合栈) Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- HDU 2222 Keywords Search(查询关键字)
HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...
- HDU 3549 Flow Problem(最大流)
HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...
随机推荐
- C语言变长数组data[0]【总结】
1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data ...
- Redis:解决分布式高并发修改同一个Key的问题
本篇文章是通过watch(监控)+mutil(事务)实现应用于在分布式高并发处理等相关场景.下边先通过redis-cli.exe来测试多个线程修改时,遇到问题及解决问题. 高并发下修改同一个key遇到 ...
- Linux下逻辑地址-线性地址-物理地址图解(转)
一.逻辑地址转线性地址 机器语言指令中出现的内存地址,都是逻辑地址,需要转换成线性地址,再经过MMU(CPU中的内存管理单元)转换成物理地址才能够被访问到. 我们写个最简单的hello world程序 ...
- Ubuntu 突然上不去网了怎么办
到家了也想看看程序.打开WIN8上的虚拟机VM,然后启动Ubuntu.................................... 像往常一样等待着界面,输入password,然后改动程序. ...
- Core Java-多线程-线程的生命周期
0. 在介绍线程前我们先看一下什么是进程? 进程是线程的母亲,如果在大学计算机课程里读过操作系统一定不会陌生. 所谓进程,它是计算机程序关于某数据集上的一次活动,是系统进行资源分配和调度的基本单位,是 ...
- Objective-C编程 - 关于Block的要点
1. 首先,我们快速过一下,什么是Block? Block是一段代码,它在OC中以^开头,可以有返回值,和参数列表,但就是没有名字. 所以,你可以把它认为是匿名函数. 事实上,它和Swift中的闭包( ...
- Python3中使用Mysql的用法。
一.Python2中一般使用MySqldb来调用Mysql,但是在Python3中不支持该包,使用pymysql来代替了,用法一模一样. 二.安装: pip install pymysql 三.例子: ...
- Hibernate学习笔记一:项目创建与基本配置文件
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6760773.html 一:ORM ORM:对象-关系 映射. 即:把Java中有关联关系的对象,转换成关系型 ...
- Maven依赖传递、依赖传递排除、依赖冲突
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6628429.html 一:Maven依赖传递 假如有Maven项目A,项目B依赖A,项目C依赖B.那么我们可 ...
- CUPS/Printer sharing
https://wiki.archlinux.org/index.php/CUPS/Printer_sharing_(简体中文) GNU/Linux系统间共享 在作为打印服务器的GNU/Linux ...