BZOJ3144【HNOI2013】切糕
来源:互联网 发布:msdb数据库下载 编辑:程序博客网 时间:2024/04/25 07:59
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3144
【分析】
所有人都说这是个经典的最小割模型......蒟蒻泪流满面......
建一个r+1层的,每层都是p*q的图,从源出发向第一层连inf的边,从第r+1层上每个点出发向汇连inf的边,对i,j,k与i,j,k+1之间连v(i,j,k)的边。
如果没有高度限制,那么这么做就是在每一条纵轴上选一个点。
因为有高度限制,所以对于每个层数大于d的点,要向x,y坐标相邻的,层数小d的点连一条inf的边。
以p=1,q=2,r=5,d=2为例。(先忽略从右边较高的点连向左边较低的点的那些边)
下面是源,上面是汇。如图所示,如果我把图中的红边割掉,那么图中的蓝边也就没有用了。如果此时把绿边割掉,那么还是存在一条从源到汇的路径;如果割绿色的边上面的边,那么源到汇就没有路径可达了。
仔细理解一下,也就是在左边选了一条边以后,右边的高度小于当前边的边就不能选了。如果把右上向左下连的边也连起来,那么高度就完全限制住了。
然后跑一下最大流就好了。
【代码】
#include <cstdio>#include <algorithm>using namespace std;const int maxl=45,maxn=75000,maxm=maxn<<4,inf=~0U>>1,mov[4][2]={{0,1},{1,0},{0,-1},{-1,0}};int head[maxn],next[maxm],E[maxm],F[maxm],Ecnt;int id[maxl][maxl][maxl];int p,q,r,d;int s,e;inline void Add_Edge(int x,int y,int f) {next[++Ecnt]=head[x];head[x]=Ecnt;E[Ecnt]=y;F[Ecnt]=0;next[++Ecnt]=head[y];head[y]=Ecnt;E[Ecnt]=x;F[Ecnt]=f;}void Init(){scanf("%d%d%d%d",&p,&q,&r,&d);int cnt=0,x;Ecnt=1;s=++cnt;for (int i=1;i<=r+1;i++)for (int j=1;j<=p ;j++)for (int k=1;k<=q ;k++)id[i][j][k]=++cnt;e=++cnt;for (int i=1;i<=r;i++)for (int j=1;j<=p;j++)for (int k=1;k<=q;k++)scanf("%d",&x),Add_Edge(id[i][j][k],id[i+1][j][k],x);for (int i=1;i<=p;i++)for (int j=1;j<=q;j++)Add_Edge(s,id[1][i][j],inf),Add_Edge(id[r+1][i][j],e,inf);#define nx (j+mov[mv][0])#define ny (k+mov[mv][1])for (int i=d+1;i<=r+1;i++)for (int j=1;j<=p;j++)for (int k=1;k<=q;k++)for (int mv=0;mv<4;mv++)if (id[i][nx][ny])Add_Edge(id[i][j][k],id[i-d][nx][ny],inf);#undef nx#undef ny}int Q[maxn],Vis[maxn],h[maxn];bool BFS(int time){int top=1,tail=1;Q[1]=s;Vis[1]=time;h[1]=0;while (top<=tail){int x=Q[top++],hx=h[x];for (int i=head[x];i;i=next[i]) if (Vis[E[i]]!=time && F[i^1])h[E[i]]=h[x]+1,Vis[E[i]]=time,Q[++tail]=E[i];if (Vis[e]==time) break;}return Vis[e]==time;}int DFS(int x,int f){if (x==e) return f;int res=f;for (int i=head[x];i && res;i=next[i]) if (h[E[i]]==h[x]+1 && F[i^1]){int d=DFS(E[i],min(F[i^1],res));res-=d;F[i]+=d;F[i^1]-=d;}if (f==res) h[x]=-1;return f-res;}void Dinic(){int res=0,time=0;while (BFS(++time)) res+=DFS(s,inf);printf("%d\n",res);}int main(){Init();Dinic();return 0;}
0 0
- BZOJ3144【HNOI2013】切糕
- bzoj3144: [Hnoi2013]切糕
- bzoj3144【HNOI2013】切糕
- [BZOJ3144][HNOI2013]切糕
- [bzoj3144]【HNOI2013】切糕
- BZOJ3144: [Hnoi2013]切糕
- BZOJ3144: [Hnoi2013]切糕
- BZOJ3144: [Hnoi2013]切糕
- [题解]bzoj3144(HNOI2013)切糕
- 【bzoj3144】[Hnoi2013]切糕
- bzoj3144 [Hnoi2013]切糕
- 【bzoj3144】[Hnoi2013]切糕
- bzoj3144 [Hnoi2013]切糕
- 【bzoj3144】【HNOI2013】【切糕】【最小割】
- 【BZOJ3144】[Hnoi2013]切糕【最小割】
- [BZOJ3144][HNOI2013]切糕-网络流
- [BZOJ3144][HNOI2013]切糕 最小割
- bzoj3144: [Hnoi2013]切糕 DINIC最小割
- 树形dp学习笔记
- 第八周项目4——String类的构造
- [黑马程序员]9 JAVA基础- 网络编程
- mybatis下处理mysql中的blob
- 前端开发HTML5和CSS3的强有力前端js检测类库:js框架Modernizr
- BZOJ3144【HNOI2013】切糕
- 第8周项目1-3使实数与复数进行运算用friend函数
- 黑马程序员——java-多线程
- 摘录 - 技术类
- 数据结构与算法复习之排序算法——冒泡、插入、快排、归并
- Modernizr的介绍和使用
- 调试miracl遇到的lib问题
- 第七周 项目1-图形用户界面应用程序开发初体验
- HDU-2546 饭卡(DP)