BZOJ1001
来源:互联网 发布:常州青蓝软件 编辑:程序博客网 时间:2024/05/19 19:30
开坑!
1001: [BeiJing2006]狼抓兔子
思路:平面图最小割
Orz周冬,主要思想都在他的文章《浅析最大最小定理在信息学竞赛中的应用》中提到
显然最大流不现实
将整个图从斜线切开,分为两块
若我们将每一块区域看成一个点,两块区域的公共边作为这两点的连边
显然,从左下到右上的最短路就是整个图的最小割
真是神思想!
代码:
我这个人比较喜欢手写优先队列……
#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 longusing 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<<30int 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;}
0 0
- BZOJ1001
- BZOJ1001
- bzoj1001
- bzoj1001
- bzoj1001
- BZOJ1001题解
- bzoj1001 spfa
- BZOJ1001(狼抓兔子)
- 【BZOJ1001】狼抓兔子
- BZoj1001狼抓兔子
- 【bzoj1001】【狼抓兔子】
- BZOJ1001狼抓兔子
- [bzoj1001]狼抓兔子
- 【BZOJ1001】狼抓兔子
- bzoj1001 -- 最短路
- BZOJ1001狼抓兔子
- 【BZOJ1001】【BJOI2006】狼抓兔子
- bzoj1001 平面图转对偶图
- 第四章,简单的水果机游戏(Android)
- CoreData 数据库更新,数据迁移
- nyoj 998 Sum 【欧拉函数运用】
- Training:并查集(最小生成树)
- Linux如何查看CPU温度
- BZOJ1001
- BZOJ1040 [ZJOI2008]骑士(基环树+树形dp)
- Volley框架的使用
- [LeetCode]Factorial Trailing Zeroes
- 数组中只出现一次的数字
- Xcode 中sqlite数据库的创建与数据库的导入
- telnet 测试某端口是否可用
- Leetcode[100]-Same Tree
- IBokan_ios80_自学系列_1(switch语句+if...else...语句练习)