bzoj 1001 BJOI2006 狼抓兔子 最小割
2015-01-03 23:57
232 查看
bzoj 1001 BJOI2006 狼抓兔子
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1001Description
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.
Input
第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10MOutput
输出一个整数,表示参与伏击的狼的最小数量.Sample Input
3 45 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
14本题即求最小割,难点在于建模(建对偶图):
对于每一个面,建一个点,对于每一条边,在对偶图中也连边;
#include<cstdio> #include<cstring> #include<string> #include<iostream> #include<algorithm> #include<queue> #define INF 0x3f3f3f3f #define MAXN 3000000+10 using namespace std; bool used[MAXN]; int n,m,e,t; int to[MAXN],next[MAXN],edge[MAXN],val[MAXN],dis[MAXN]; struct Node { int v,dis; Node(int x,int y) { v=y; dis=x; } bool operator <(Node x)const { return dis>x.dis; } }; void addedge(int x,int y,int v) { e++; to[e]=y; val[e]=v; next[e]=edge[x]; edge[x]=e; } void Dijstra() { memset(dis,INF,sizeof(dis)); priority_queue<Node> q; dis[0]=0; q.push(Node(dis[0],0)); while(!q.empty()) { Node tmp=q.top(); q.pop(); if(!used[tmp.v]) { int k=tmp.v; used[k]=true; for(int i=edge[k]; i; i=next[i]) if(!used[to[i]]) { if(dis[to[i]]>dis[k]+val[i]) { dis[to[i]]=dis[k]+val[i]; q.push(Node(dis[to[i]],to[i])); } } } } printf("%d",dis[t]); } bool check() { if(n==1) { int ans=INF; for(int i=1,res; i<=m; i++) { scanf("%d",&res); ans=min(res,ans); } printf("%d",ans); return false; } if(m==1) { int ans=INF; for(int i=1,res; i<=n; i++) { scanf("%d",&res); ans=min(res,ans); } printf("%d",ans); return false; } return true; } void make_map() { int res; t=2*(n-1)*(m-1)+1; for(int i=1; i<m; i++) { scanf("%d",&res); addedge(i*2,t,res); } for(int i=1; i<n-1; i++) { for(int j=1; j<m; j++) { scanf("%d",&res); addedge(i*(m-1)*2+j*2,(i-1)*(m-1)*2-1+j*2,res); } } for(int i=1; i<m; i++) { scanf("%d",&res); addedge(0,(n-2)*(m-1)*2-1+i*2,res); } for(int i = 0; i < n - 1; i++) { scanf("%d",&res); addedge(0,i * (m - 1) * 2 + 1,res); for(int j = 1; j < m - 1; j++) { scanf("%d",&res); addedge(i * (m - 1) * 2 + j * 2,i * (m - 1) * 2 + j * 2 + 1,res); } scanf("%d",&res); addedge((i + 1) * (m - 1) * 2,t,res); } //step3: for(int i = 0; i < n - 1; i++) { for(int j = 1; j < m; j++) { scanf("%d",&res); addedge(i * (m - 1) * 2 + j * 2 - 1,i * (m - 1) * 2 + j * 2,res); } } } void work() { make_map(); Dijstra(); } void readdata() { scanf("%d%d",&n,&m); if(check()) work(); } int main() { readdata(); return 0; }
相关文章推荐
- [BJOI2006][bzoj1001] 狼抓兔子 [最小割]
- BZOJ1001 BJOI2006狼抓兔子(最小割+最短路)
- BZOJ1001 [BeiJing2006]狼抓兔子(平面图最小割转最短路)
- BZOJ1001: [BeiJing2006]狼抓兔子 (最小割)
- BZOJ 1001: [BeiJing2006]狼抓兔子 【最小割】
- bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割
- BZOJ1001: [BeiJing2006]狼抓兔子 (最小割)
- 最小割——BZOJ1001 [BeiJing2006]狼抓兔子
- 平面圖最小割 BZOJ1001: [BeiJing2006]狼抓兔子 BZOJ 2007: [Noi2010]海拔
- BZOJ 1001: [BeiJing2006]狼抓兔子 最小割
- 【最小割+对偶图=最短路】BZOJ1001 [BeiJing2006]狼抓兔子
- 【平面图】【最小割】【最短路】【Heap-Dijkstra】bzoj1001 [BeiJing2006]狼抓兔子
- 【最小割->最短路】BZOJ1001(BeiJing2006)[狼抓兔子]题解
- 【BJOI2006】bzoj1001 狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】
- [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)
- bzoj1001 [BeiJing2006]狼抓兔子(最小割/平面图最大流转对偶图最短路)
- BZOJ 1001 Beijing 2006 狼抓兔子 最小割
- 【BZOJ】【1001】 【BJOI2006】狼抓兔子
- [BJOI2006] [BZOJ1001] 狼抓兔子|最大流|最短路