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/ ...
随机推荐
- Linq-排序Order By
适用场景:对查询出的语句进行排序,比如按时间排序等等. 说明:按指定表达式对集合排序:延迟,:按指定表达式对集合排序:延迟,默认是升序,加上descending表示降序,对应的扩展方法是OrderBy ...
- git Alias 设置
git Alias 设置 Git 使用比較多的话能够设置一些命令的 Alias ,简单的说就是用简写取代整个完整的命令. 如co 代表 checkout. Mac下,到根文件夹 cd ~ 然后 vi ...
- destoon源码解读
一.module module值:表示模块的id ID1.核心: ID2.会员: ID3.扩展: 当ID>3时,为购买.公司等模块. dt:为各种变量,相当于整站的配置,如:关键词.描述.积分等 ...
- js开发思路
$.ui = $.ui || {}; var version = $.ui.version = "1.12.1"; // 是否为ie浏览器 var ie = $.ui.ie = ! ...
- asp.net正则表达式类的定义
using System; using System.Collections; using System.Reflection; using System.Reflection.Emit; using ...
- linux 查看网线断开 网卡是否关闭
linux 查看网线断开 网卡是否关闭 探测是否存在网络接口: SIOCGIFFLAGS
- 使用Chrome保存网页为mht文件
一直在使用chrome浏览器,但由于需要将部分网页保存为mht文件,却发现chrome默认不支持.chrome浏览器默认支持2种:单独的html文件,全部: 万能的chrome怎么可能保存不了mht? ...
- 【树莓派】树莓派上面安装配置teamviewer
访问树莓派桌面,的另一种方式,就是使用Teamviewer. 参考这篇文章做了实验:http://www.linuxdiyf.com/linux/16887.html,对其中部分进行了件要整理和总结. ...
- NIO SelectionKey attachment()空指针错误
Channel注册到Selector时添加了一个Object: serverSocketChannel1.register(selector, SelectionKey.OP_ACCEPT, num[ ...
- java推断字符串中是否包括字母
1.java代码推断字符串中是否包括字母: 思路:使用正則表達式的来验证 1.1演示样例代码例如以下: /** * 该方法主要使用正則表達式来推断字符串中是否包括字母 * @author fengga ...