BZOJ1001 狼抓兔子
Posted ljh2000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1001 狼抓兔子相关的知识,希望对你有一定的参考价值。
题意:给一个网格图,然后横向、竖向、斜向都有边相连,然后问图的最小割
正解:Dicnic(裸网络流)
上网查满地跑的对偶图,然后学了一下对偶图,但并不打算用转对偶图,尽管好像很简单
于是试图用Dicnic强上,直接把每条边连进去,暴力网络流。
就当网络流练手题吧。
值得一提的是,需要用一些优化不然会TLE:当发现拓展到当前的结点发现可拓展流量为0,那么这个点在这下一次重新BFS建分层图时显然不会再用的上(画个图yy一下就可以了) 所以直接dis[now]=-1,相当于把它“堵塞”住了。
//It is made by jump~ #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <ctime> #include <vector> #include <queue> #include <map> #ifdef WIN32 #define OT "%I64d" #else #define OT "%lld" #endif using namespace std; typedef long long LL; const int MAXM = 6000011; const int MAXN = 1000011; int inf; int n,m; int first[MAXN]; int ecnt; int s,t; int dis[MAXN]; int ans; struct edge{ int v,f; int next; }e[MAXM]; inline int getint() { int w=0,q=0; char c=getchar(); while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar(); if (c==‘-‘) q=1, c=getchar(); while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar(); return q ? -w : w; } inline void link(int x,int y,int z){ e[++ecnt].next=first[x]; first[x]=ecnt; e[ecnt].v=y; e[ecnt].f=z; e[++ecnt].next=first[y]; first[y]=ecnt; e[ecnt].v=x; e[ecnt].f=z; } inline bool bfs(){ memset(dis,127/3,sizeof(dis)); int cun=dis[t]; queue<int>Q; while(!Q.empty()) Q.pop(); dis[1]=1; Q.push(1); while(!Q.empty()) { int u=Q.front(); Q.pop(); for(int i=first[u];i;i=e[i].next) { if(e[i].f && dis[e[i].v]==cun) { dis[e[i].v]=dis[u]+1; Q.push(e[i].v); } } if(dis[t]!=cun) return true; } return false; } inline int maxflow(int now,int remain){ if(remain==0 || now==t) return remain; int flow=0; for(int i=first[now];i;i=e[i].next){ if(dis[e[i].v]==dis[now]+1 && e[i].f){ int f=maxflow(e[i].v,min(remain,e[i].f)); if(f) { e[i].f-=f; e[i^1].f+=f; flow+=f; remain-=f; if(remain==0) return flow; } else dis[e[i].v]=-1; } } return flow; } inline void solve(){ s=1,t=n*m; inf=1; for(int i=1;i<=30;i++) inf*=2; while(bfs()) { ans+=maxflow(s,inf); } printf("%d",ans); } int main() { n=getint(); m=getint(); int x; ecnt=1; int nowx,nownex; for(int i=1;i<=n;i++) for(int j=1;j<m;j++){ nowx=(i-1)*m+j,nownex=nowx+1; x=getint(); link(nowx,nownex,x); } for(int i=1;i<n;i++) for(int j=1;j<=m;j++) { nowx=(i-1)*m+j,nownex=nowx+m; x=getint(); link(nowx,nownex,x); } for(int i=1;i<n;i++) for(int j=1;j<m;j++) { nowx=(i-1)*m+j,nownex=nowx+m+1; x=getint(); link(nowx,nownex,x); } solve(); return 0; }
以上是关于BZOJ1001 狼抓兔子的主要内容,如果未能解决你的问题,请参考以下文章