bzoj-1001 狼抓兔子
2015-08-12 15:38
253 查看
题意:
给出一个n*m的下面这样的图,求此图的最小割;
n,m<=1000;
题解:
这题说好的简单题结果怎么如此丧病;
最简单的想法就是求最小割就是求最小割嘛;
然后一发Dinic搞定;
然而似乎现在不能这么A了= =
所以这个图有一些特殊的性质,这是一个平面图;
而对于一个平面图的割来说,一定是一条曲线割开了一些线段;
那么如果将这些平面视为点,边视为连接两个平面的边;
那么从左下的平面连到右上区域的一条最短路就是此图的最小割了;
内存好大啊。。时间复杂度大概是O(k*n*m);
思路简单细节有点恶心;
1.加边记得双向;
2.n==1或m==1特判;
3.读入各种n,m弄反。。
代码:
给出一个n*m的下面这样的图,求此图的最小割;
n,m<=1000;
题解:
这题说好的简单题结果怎么如此丧病;
最简单的想法就是求最小割就是求最小割嘛;
然后一发Dinic搞定;
然而似乎现在不能这么A了= =
所以这个图有一些特殊的性质,这是一个平面图;
而对于一个平面图的割来说,一定是一条曲线割开了一些线段;
那么如果将这些平面视为点,边视为连接两个平面的边;
那么从左下的平面连到右上区域的一条最短路就是此图的最小割了;
内存好大啊。。时间复杂度大概是O(k*n*m);
思路简单细节有点恶心;
1.加边记得双向;
2.n==1或m==1特判;
3.读入各种n,m弄反。。
代码:
#include<queue> #include<stdio.h> #include<string.h> #include<algorithm> #define N 2500000 using namespace std; queue<int>q; int to[N<<2],next[N<<2],val[N<<2],head ,tot; int num[2100][1100],s,t; int dis ; bool inq ; void add(int x,int y,int v) { to[++tot]=y,next[tot]=head[x],val[tot]=v,head[x]=tot; } int spfa() { memset(dis,0x3f,sizeof(dis)); dis[s]=0,inq[s]=1; q.push(s); int x,y,i; while(!q.empty()) { x=q.front(),q.pop(); inq[x]=0; for(i=head[x];i;i=next[i]) { if(dis[y=to[i]]>dis[x]+val[i]) { dis[y]=dis[x]+val[i]; if(!inq[y]) inq[y]=1,q.push(y); } } } return dis[t]; } void SPJ(int n) { int ret=0x3f3f3f3f,x; for(int i=1;i<n;i++) { scanf("%d",&x); ret=min(ret,x); } printf("%d\n",ret); exit(0); } int main() { int n,m,i,j,k,x,y,v; scanf("%d%d",&n,&m); if(n==1||m==1) SPJ(n==1?m:n); for(i=1,k=0;i<=n+n-2;i++) for(j=1;j<m;j++) num[i][j]=++k; s=++k,t=++k; for(i=1;i<m;i++) { scanf("%d",&v); add(num[1][i],t,v); } for(i=2;i<n;i++) { for(j=1;j<m;j++) { scanf("%d",&v); add(num[i+i-1][j],num[i+i-2][j],v); add(num[i+i-2][j],num[i+i-1][j],v); } } for(i=1;i<m;i++) { scanf("%d",&v); add(s,num[n+n-2][i],v); } for(i=1;i<n;i++) { scanf("%d",&v); add(s,num[i+i][1],v); for(j=1;j<m-1;j++) { scanf("%d",&v); add(num[i+i-1][j],num[i+i][j+1],v); add(num[i+i][j+1],num[i+i-1][j],v); } scanf("%d",&v); add(num[i+i-1][m-1],t,v); } for(i=1;i<n;i++) { for(j=1;j<m;j++) { scanf("%d",&v); add(num[i+i][j],num[i+i-1][j],v); add(num[i+i-1][j],num[i+i][j],v); } } printf("%d\n",spfa()); return 0; }
相关文章推荐
- 好用的eclipse properties插件
- [hdu4629 Burning]三角形面积并,扫描线
- socket学习笔记——IO口的基本操作(读、写)
- 【JDK配置原创】JDK(JRE)环境变量配置原理 --费元星
- Memcache 问题集锦
- iOS项目开发实战——通过Http Get方式与服务器通信
- 8583报文MAC验证实现过程
- 用Git 进行分布式代码管理
- 如何在Windows7上使用Hyper-V
- JSP EL表达式详细介绍
- Yii2.0中文开发向导——查询条件Where全解析
- 简单的MySQL备份与还原方法分享
- 组合数学的一些常见公式
- 华为OJ(挑7)
- extern “C”详细介绍
- Javascript识别各种浏览器、渲染引擎、系统平台(操作系统|移动设备|游戏系统)
- Calendar中的一些方法
- 又见回文
- 【Java】Java代码经典错误清单
- 在TextField 的协议shouldChangeCharactersInRange输出textfield中在改变的所有内容