BZOJ1001
2015-06-11 18:13
411 查看
开坑!
Orz周冬,主要思想都在他的文章《浅析最大最小定理在信息学竞赛中的应用》中提到
显然最大流不现实
将整个图从斜线切开,分为两块
若我们将每一块区域看成一个点,两块区域的公共边作为这两点的连边
显然,从左下到右上的最短路就是整个图的最小割
真是神思想!
代码:
我这个人比较喜欢手写优先队列……
1001: [BeiJing2006]狼抓兔子
思路:平面图最小割Orz周冬,主要思想都在他的文章《浅析最大最小定理在信息学竞赛中的应用》中提到
显然最大流不现实
将整个图从斜线切开,分为两块
若我们将每一块区域看成一个点,两块区域的公共边作为这两点的连边
显然,从左下到右上的最短路就是整个图的最小割
真是神思想!
代码:
我这个人比较喜欢手写优先队列……
[code]#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <algorithm> #define debug(...) fprintf(stderr,__VA_ARGS__) #define rint register int #define ull unsigned long long using namespace std; const int MAXN=2*1000*1000+10,MAXM=6*1000*1000+10; int n,m; int s,t; #define heng(a,b) ((a-1)*2-(1-b))*(m-1) #define inf 1<<30 int frontx[MAXM],fronty[MAXM],frontk[MAXM]; int stdx[MAXN],orderx[MAXM]; int nn,mm; void add(int x,int y,int k) { if (x!=t) { frontx[++mm]=x; fronty[mm]=y; frontk[mm]=k; } if (y!=s) { frontx[++mm]=y; fronty[mm]=x; frontk[mm]=k; } return ; } int num[MAXN]; void Read(int &k) { char c=getchar(); k=0; while (c<'0' || c>'9') c=getchar(); while (c>='0' && c<='9') { k=k*10+c-'0'; c=getchar(); } return ; } void sortx() { for (rint i=1;i<=mm;i++) num[frontx[i]]++; for (rint i=1;i<=nn;i++) { num[i]+=num[i-1]; stdx[i]=num[i]; } for (rint i=1;i<=mm;i++) orderx[++num[frontx[i]-1]]=i; return ; } struct Heap { unsigned int dis; int x; }heap[MAXN]; bool operator < (Heap A,Heap B) { return A.dis<B.dis; } int point[MAXN]; void adjustup(int x) { static bool next; next=true; while (next) { next=false; static int f; f=x/2; if (f) if (heap[x]<heap[f]) { swap(heap[x],heap[f]); point[heap[x].x]=x; point[heap[f].x]=f; x=f; next=true; }} return ; } void change(int l,int r) { swap(heap[l],heap[r]); point[heap[r].x]=r; point[heap[l].x]=l; return ; } void adjustdown(int x) { static bool next; next=true; while (next) { next=false; static int l,r; l=x*2,r=x*2+1; if (l<=nn) if (r<=nn) { if (heap[l]<heap[r] && heap[l]<heap[x]) { change(l,x); x=l; next=true; } else if (heap[r]<heap[x]) { change(r,x); x=r; next=true; } else if (heap[l]<heap[x]) { change(l,x); x=l; next=true; }}} return ; } void dijsktra() { for (rint i=1;i<=nn;i++) { heap[i].dis=inf; point[i]=heap[i].x=i; } heap[s].dis=0; adjustup(s); while (nn) { static Heap now; now=heap[1]; if (now.x==t) { cout<<heap[point[t]].dis<<endl; return ; } change(1,nn); nn--; adjustdown(1); static int x; x=now.x; for (rint i=stdx[x-1]+1;i<=stdx[x];i++) { static int next; next=fronty[orderx[i]]; if (heap[point[next]].dis>now.dis+frontk[orderx[i]]) { heap[point[next]].dis=now.dis+frontk[orderx[i]]; adjustup(point[next]); }}} return ; } void init() { Read(n); Read(m); if (n==1 || m==1) { int nn=n,ans=inf; if (nn==1) nn=m; for (int k,i=1;i<nn;i++) { Read(k); ans=min(ans,k); } if (ans==inf) cout<<0<<endl; else cout<<ans<<endl; return ; } s=(n-1)*(m-1)*2+1,t=(n-1)*(m-1)*2+2; nn=t; for (rint i=1;i<=n;i++) for (rint k,j=1;j<m;j++) { Read(k); if (i==1) add(s,heng(i,1)+j,k); else if (i==n) add(heng(i,0)+j,t,k); else add(heng(i,0)+j,heng(i,1)+j,k); } for (rint i=1;i<n;i++) for (rint k,j=1;j<=m;j++) { Read(k); if (j==1) add(t,heng(i+1,0)+j,k); else if (j==m) add(s,heng(i,1)+j-1,k); else add(heng(i,1)+j-1,heng(i+1,0)+j,k); } for (rint i=1;i<n;i++) for (rint k,j=1;j<m;j++) { Read(k); add(heng(i,1)+j,heng(i+1,0)+j,k); } sortx(); dijsktra(); return ; } int main() { init(); return 0; }
相关文章推荐
- 【性能诊断】四、单功能场景的性能分析(RedGate,找到同一个客户端的并发请求被串行化问题)
- [FZYZOJ 1204] 零和问题
- 【待续】Centos7安装完后无法进入图形界面(GNOME/KDE)的解决方
- cobbler
- 前端笔记
- QT菜单栏添加
- Training:并查集(最小生成树)
- nyoj 998 Sum 【欧拉函数运用】
- Linux如何查看CPU温度
- 层次分析法
- easy_install jinja2 mac linux
- 要嫁就嫁给成功,要输就输给追求
- HBase在内容推荐引擎系统中的应用
- 对VC++下Debug模式和Release模式的简要分析
- 17年后回国
- 列表
- CryptoJS AES加密、解密练习demo
- 2015年5月信息系统项目管理师综合知识真题详解 11-20题
- MSSQL - sql server 2008安装时服务器配置,SQL server服务指定的凭证无效
- IIS日志自动删除程序