[BZOJ 1001][BeiJing2006]狼抓兔子(网络流/SPFA)
2017-02-28 07:44
417 查看
Description
现在小朋友们最喜欢的”喜羊羊与灰太狼”,话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(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个数,表示斜向道路的权值.
输入文件保证不超过10M
Output
输出一个整数,表示参与伏击的狼的最小数量.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
14Solution
感觉建图很鬼畜网络流
很直白的网络流#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<queue> #define Min(a,b) (a<b?a:b) #define INF 0x3f3f3f3f #define MAXN 1000003 using namespace std; int n,m; int head[MAXN],level[MAXN],cnt=0; struct Node{ int next,to,cap; }Edges[MAXN*6]; void addedge(int u,int v,int c) { Edges[cnt].next=head[u]; Edges[cnt].to=v; Edges[cnt].cap=c; head[u]=cnt++; } bool bfs() { memset(level,-1,sizeof(level)); queue<int>q; q.push(1); level[1]=0; while(!q.empty()) { int u=q.front(); for(int i=head[u];~i;i=Edges[i].next) { int v=Edges[i].to; if(level[v]<0&&Edges[i].cap) { level[v]=level[u]+1; q.push(v); } } q.pop(); } if(level[n*m]<0)return false; return true; } int dfs(int u,int flow) { if(u==n*m)return flow; int Mflow=0; for(int i=head[u];~i&&Mflow<flow;i=Edges[i].next) { int v=Edges[i].to; if(level[v]==level[u]+1&&Edges[i].cap) { int d=dfs(v,Min((flow-Mflow),Edges[i].cap)); Edges[i].cap-=d; Edges[i^1].cap+=d; Mflow+=d; } } if(!Mflow)level[u]=-1; return Mflow; } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<m;j++) { int c; scanf("%d",&c); addedge((i-1)*m+j,(i-1)*m+j+1,c); addedge((i-1)*m+j+1,(i-1)*m+j,c); } for(int i=1;i<n;i++) for(int j=1;j<=m;j++) { int c; scanf("%d",&c); addedge((i-1)*m+j,i*m+j,c); addedge(i*m+j,(i-1)*m+j,c); } for(int i=1;i<n;i++) for(int j=1;j<m;j++) { int c; scanf("%d",&c); addedge((i-1)*m+j,i*m+j+1,c); addedge(i*m+j+1,(i-1)*m+j,c); } int Maxflow=0,x; while(bfs()) { while(x=dfs(1,INF)) {Maxflow+=x;} } printf("%d\n",Maxflow); return 0; }
SPFA
Update:今天忽然想补一个SPFA平面图转对偶图然后SPFA求最小割
m==1||n==1要特判
可是
4000
它为什么变慢了啊喂…而且慢了这么多
难道是我写挂了
失去信仰
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<queue> #define inf 0x3f3f3f3f using namespace std; int n,m; int head[2500000],cnt=0; struct Node{ int next,to,w; }Edges[7000000]; bool inq[2500000]; int dis[2500000]; void addedge(int u,int v,int w) { Edges[cnt].next=head[u]; head[u]=cnt; Edges[cnt].to=v; Edges[cnt++].w=w; } int SPFA(int s,int t) { memset(inq,0,sizeof(inq)); memset(dis,0x3f,sizeof(dis)); queue<int>q; q.push(s); dis[s]=0;inq[s]=1; while(!q.empty()) { int u=q.front(); for(int i=head[u];~i;i=Edges[i].next) { int v=Edges[i].to; if(dis[u]+Edges[i].w<dis[v]) { dis[v]=dis[u]+Edges[i].w; if(!inq[v]) { inq[v]=1; q.push(v); } } } q.pop(); inq[u]=0; } return dis[t]; } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); int c,u,v; int s=0,t=(n-1)*(m-1)*2+1; if(n==1||m==1) { int ans=inf; while(~scanf("%d",&c)) if(c<ans)ans=c; printf("%d\n",ans); return 0; } for(int i=1;i<=n;i++) for(int j=1;j<=m-1;j++) { scanf("%d",&c); if(i==1) { addedge(s,j,c); addedge(j,s,c); } else if(i==n) { u=((n-1)*2-1)*(m-1)+j; addedge(u,t,c); addedge(t,c,u); } else { u=((i-1)*2-1)*(m-1)+j; v=(i-1)*2*(m-1)+j; addedge(u,v,c); addedge(v,u,c); } } for(int i=1;i<=n-1;i++) for(int j=1;j<=m;j++) { scanf("%d",&c); if(j==1) { u=(i*2-1)*(m-1)+1; addedge(u,t,c); addedge(t,u,c); } else if(j==m) { u=((i-1)*2+1)*(m-1); addedge(u,s,c); addedge(s,u,c); } else { u=(i-1)*2*(m-1)+j-1; v=(i*2-1)*(m-1)+j; addedge(u,v,c); addedge(v,u,c); } } for(int i=1;i<=n-1;i++) for(int j=1;j<=m-1;j++) { scanf("%d",&c); u=(i-1)*2*(m-1)+j; v=((i-1)*2+1)*(m-1)+j; addedge(u,v,c); addedge(v,u,c); } printf("%d\n",SPFA(s,t)); return 0; }
相关文章推荐
- bzoj1001 [BeiJing2006]狼抓兔子(网络流dinic算法||最短路spfa)
- bzoj1001: [BeiJing2006]狼抓兔子(网络流模板题:最大流)
- BZOJ1001: [BeiJing2006]狼抓兔子 [最小割 | 对偶图+spfa]
- BZOJ1001(BeiJing2006)[狼抓兔子]题解--最小割&spfa
- BZOJ1001 [BeiJing2006]狼抓兔子(网络流最小割)
- [bzoj1001][BeiJing2006]狼抓兔子_网络流_最小割转对偶图
- 【bzoj1001】【BeiJing2006】【狼抓兔子】【网络流】【平面图转对偶图】
- 【BZOJ 1001】[BeiJing2006]狼抓兔子
- 【BZOJ 1001】【Beijing 2006】狼抓兔子
- 平面圖最小割 BZOJ1001: [BeiJing2006]狼抓兔子 BZOJ 2007: [Noi2010]海拔
- [bzoj1001][BeiJing2006]狼抓兔子
- [bzoj1001][BeiJing2006]狼抓兔子
- 【BZOJ1001】[BeiJing2006]狼抓兔子
- BZOJ 1001 [BeiJing2006] 狼抓兔子
- [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)
- bzoj 1001: [BeiJing2006]狼抓兔子(s-t平面图求最大流)
- 【BZOJ1001】【Beijing2006】狼抓兔子(平面图转对偶图:最小割+最短路)
- bzoj1001: [BeiJing2006]狼抓兔子
- BZOJ1001 [BeiJing2006]狼抓兔子(平面图最小割转最短路)
- [最小割+对偶建图+最短路] BZOJ1001: [BeiJing2006]狼抓兔子