博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[洛谷P2774] 方格取数问题
阅读量:5056 次
发布时间:2019-06-12

本文共 2434 字,大约阅读时间需要 8 分钟。

题意

在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。


想法

我们将问题转化为:一开始所有格子都选,之后去掉价值和最少的一些格子使剩下的格子合法。

将方格黑白染色,白格子连向S,黑格子连向T,边权为这个格子的值(也就是说将格子转移到边上)。
相邻的黑白格子间连INF的边。(这样每条从S到T的路径都为 S->白格子->黑格子->T , 这两个格子不能同时选,S->白格子 与 黑格子->T 间必然会割掉一条边)
注意一个小trick:对于永远不被割掉的边,边权设为INF
这样跑完最小割后,剩下的格子是合法的。而最小割的容量便为去掉的那些格子的价值和。


代码

#include
#include
#include
#define INF 2000000000using namespace std;typedef long long ll;const int N = 10005;struct node{ int v,f; node *next,*rev; }pool[N*20],*h[N];int cnt;void addedge(int u,int v,int f){ node *p=&pool[++cnt],*q=&pool[++cnt]; p->v=v;p->next=h[u];h[u]=p; p->f=f;p->rev=q; q->v=u;q->next=h[v];h[v]=q; q->f=0;q->rev=p; }int S,T;int que[N],level[N];bool bfs(){ int head=0,tail=0,u,v; for(int i=S;i<=T;i++) level[i]=-1; level[S]=1; que[tail++]=S; while(head
next) if(p->f && level[v=p->v]==-1){ level[v]=level[u]+1; que[tail++]=v; } if(level[T]!=-1) return true; } return false;}int find(int u,int f){ int v,s=0,t; if(u==T) return f; for(node *p=h[u];p;p=p->next) if(p->f && s
v]==level[u]+1){ t=find(v,min(f-s,p->f)); if(t){ s+=t; p->f-=t; p->rev->f+=t; } } if(!s) level[u]=-1; return s;}ll dinic(){ ll f=0; while(bfs()) f+=find(S,INF); return f;}int n,m;int val[105][105];bool check(int x,int y){ if(x<1 || y<1 || x>n || y>m) return false; return true; }int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&val[i][j]); ll sum=0; S=0; T=n*m+1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ sum=sum+val[i][j]; if((i+j)&1) addedge(S,(i-1)*m+j,val[i][j]); else{ addedge((i-1)*m+j,T,val[i][j]); continue; } for(int dx=-1;dx<2;dx++) for(int dy=-1;dy<2;dy++) if(dx*dy==0 && dx!=dy){ int t1=i+dx,t2=j+dy; if(check(t1,t2)) addedge((i-1)*m+j,(t1-1)*m+t2,INF); } } sum-=dinic(); printf("%lld\n",sum); return 0; }

转载于:https://www.cnblogs.com/lindalee/p/8719054.html

你可能感兴趣的文章
[国嵌攻略][164][USB驱动程序设计]
查看>>
C# 实现Bresenham算法(vs2010)
查看>>
基于iSCSI的SQL Server 2012群集测试(一)--SQL群集安装
查看>>
list 容器 排序函数.xml
查看>>
存储开头结尾使用begin tran,rollback tran作用?
查看>>
Activity启动过程中获取组件宽高的五种方式
查看>>
java导出Excel表格简单的方法
查看>>
SQLite数据库简介
查看>>
利用堆实现堆排序&amp;优先队列
查看>>
Mono源码学习笔记:Console类(四)
查看>>
Android学习路线(十二)Activity生命周期——启动一个Activity
查看>>
《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇03:暂停游戏》
查看>>
CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
查看>>
windows下编译FreeSwitch
查看>>
git .gitignore 文件不起作用
查看>>
Alan Turing的纪录片观后感
查看>>
c#自定义控件中的事件处理
查看>>
hadoop1.2.1 伪分布式配置
查看>>
App.config自定义节点读取
查看>>
unity3d根据手机串号和二维码做正版验证
查看>>