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/ ...
随机推荐
- paypal 的IPN通知调用出错
一直报错: 当本地curl需要访问https时,出现SSL certificate: unable to get local issuer certificate错误信息 解决办法: 到http:// ...
- xshell5不能用
转载:xshell 5 不能用 https://51.ruyo.net/10002.html
- 例子:使用Grunt创建一个Node.js类库
创建一个文件夹. 打开命令行或者powershell, 运行npm init,根据提示填入package的信息. 在文件夹中创建index.js文件. /*! * mymongolib * Cop ...
- C++结构变量数据对齐问题
为了避免混淆.做例如以下规定,下面代码若不加特殊说明都执行于32位平台,结构体的默认对齐值是8,各数据类型所占字节数分别为 char占一个字节 int占四个字节 double占八个字节. 两个样例 请 ...
- pycharm下设置自己的模板
在File---settings---File and Code Templates---Python script 脚本里添加: #!usr/bin/env python #-*- coding:u ...
- 保存登录plsql developer 的用户名和密码
1 保存用户名 tools -> Preferences -> User Interface - Options 勾选 Autosave username . 保存 2 保存密码 tool ...
- CAD2006您没有足够的权限来安装本产品
在Win10的环境下安装CAD2006,可能会报错"您没有足够的权限来安装本产品". 解决方法是,右键以"兼容性疑难解答"运行 在弹出的对话框中,点击 &quo ...
- uni - 使用npm
一.使用 1. 在当前根目录初始化package.json npm init -y 2. 安装(自动生成node_modules文件夹) npm i packageName yarn add pack ...
- vdp介绍
In the new vSphere 5.1, there is a missing component replaced by a new one: VMware Data Recovery (VD ...
- Linux实现多线程高速下载
使用Wget下载,有时候速度挺慢的. 有没有好办法呢? 一.解决方案 安装axel 安装方法: yum -y install epel-release .el7.x86_64.rpm rpm -ivh ...