天天看點

bzoj-1001 狼抓兔子 Dinic

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;

typedef long long ll;
const int maxn=1000000+1000;
const ll INF=1e18;

struct Edge{
  
  int to,next;
  long long cap;
}edge[maxn*6];
int iter[maxn],level[maxn];
int head[maxn],edgenum;
int n,m;
void Add(int from,int to,long long cap){
  
  edge[edgenum].to=to;
  edge[edgenum].cap=cap;
  edge[edgenum].next=head[from];
  head[from]=edgenum++; 
  
  edge[edgenum].to=from;
  edge[edgenum].cap=cap;
  edge[edgenum].next=head[to];
  head[to]=edgenum++; 
}

void bfs(int s){
  
  memset(level,-1,sizeof(level));
  queue<int>que;
  level[s]=0;
  que.push(s);
  while(!que.empty()){
    
    int v=que.front();
    que.pop();
    for(int i=head[v];i!=-1;i=edge[i].next){
      
      Edge e=edge[i];
      if(e.cap>0&&level[e.to]<0){
        
        level[e.to]=level[v]+1;
        que.push(e.to);
      }
    } 
  }
}

long long dfs(int v,int t,long long f){
  
  if(v==t) return f;
  if(iter[v]==0) iter[v]=head[v];
  for(int &i=iter[v];i!=-1;i=edge[i].next){
    
    Edge &e=edge[i];
    if(e.cap>0&&level[e.to]>level[v]){
      
      long long d=dfs(e.to,t,min(e.cap,f));
      if(d>0){
        
        e.cap-=d;
        edge[i^1].cap+=d;
        return d;
      }
    }
  }
  return 0;
} 

long long max_flow(int s,int t){
  
  long long flow=0;
  for(;;){
    
    bfs(s);
    if(level[t]<0) return flow;
    memset(iter,0,sizeof(iter));
    long long f;
    while((f=dfs(s,t,INF))>0) flow+=f;
  }
}

int main(){
  
  scanf("%d%d",&n,&m);
  int tot;
  memset(head,-1,sizeof(head));
  edgenum=0;
  for(int i=0;i<n;i++){
    
    tot=0;
    for(int j=0;j<m-1;j++){
      
      long long cap;
        scanf("%lld",&cap);
        Add(i*m+tot,i*m+tot+1,cap);
        tot++;
    }
  }
  for(int i=0;i<n-1;i++){
    
    for(int j=0;j<m;j++){
      
      long long cap;
      scanf("%lld",&cap);
      Add(i*m+j,(i+1)*m+j,cap);
    }
  }
  for(int i=0;i<n-1;i++){
    
    int tot=0;
    for(int j=0;j<m-1;j++){
      
      long long cap;
      scanf("%lld",&cap);
      Add(i*m+tot,(i+1)*m+tot+1,cap);
      tot++;
    }
  }
  printf("%lld\n",max_flow(0,m*n-1));
}