[最小割] BZOJ 4823 [Cqoi2017]老C的方块

传送门

#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> abcd;

inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
  char c=nc(),b=1;
  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

namespace D{
  const int M=2500005;
  const int N=1300005;
  struct edge{
    int v,f,next;
  }G[M];
  int head[N],inum=1;
  inline void add(int u,int v,int f,int p){
    /*G[p].u=u;*/ G[p].v=v; G[p].f=f; G[p].next=head[u]; head[u]=p;
  }
  inline void link(int u,int v,int f){
    add(u,v,f,++inum); add(v,u,0,++inum);
  }
  int S,T;
  int Q[N],l,r;
  int dis[N];
#define V G[p].v
  inline bool bfs(){
    for (int i=1;i<=T;i++) dis[i]=-1;
    l=r=-1; Q[++r]=S; dis[S]=0;
    while (lint u=Q[++l];
      for (int p=head[u];p;p=G[p].next)
    if (G[p].f && dis[V]==-1){
      dis[V]=dis[u]+1; Q[++r]=V;
      if (V==T) return 1;
    }
    }
    return 0;
  }
  int cur[N];
  inline int dfs(int u,int flow){
    if (u==T) return flow;
    int used=0;
    for (int p=cur[u];p;p=G[p].next){
      cur[u]=p;
      if (G[p].f && dis[V]==dis[u]+1){
    int d=dfs(V,min(flow-used,G[p].f));
    G[p].f-=d; G[p^1].f+=d;
    used+=d; if (used==flow) break;
      }
    }
    if (!used) dis[u]=-1;
    return used;
  }
  inline int Dinic(){
    int ret=0;
    while (bfs()){
      memcpy(cur,head,sizeof(int)*(T+5));
      ret+=dfs(S,1<<30);
    }
    return ret;
  }
}

map Map;

inline int color(int x,int y){
  if ((x&1) && y%4==1) return 1;
  if ((x&1) && y%4==2) return 2;
  if ((~x&1) && y%4==3) return 2;
  if ((~x&1) && y%4==0) return 1;
  if ((x&1) && y%4==3) return 3;
  if ((~x&1) && y%4==2) return 3;
  if ((x&1) && y%4==0) return 4;
  if ((~x&1) && y%4==1) return 4;
}

const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};

int n,m,tot;

int main(){
  int x,y,w;
  using namespace D; 
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  read(n); read(m); read(tot);
  S=tot+1,T=tot+2;
  for (int i=1;i<=tot;i++)
    read(x),read(y),read(w),swap(x,y),Map[abcd(x,y)]=abcd(w,i);
  for (map::iterator it=Map.begin();it!=Map.end();it++){
    int x=it->first.first,y=it->first.second,sx,sy;
    int c=color(x,y);
    if (c==1){
      for (int k=0;k<4;k++){
    sx=x+dx[k],sy=y+dy[k];
    if (Map.count(abcd(sx,sy)) && color(sx,sy)==2)
      link(Map[abcd(x,y)].second,Map[abcd(sx,sy)].second,min(Map[abcd(x,y)].first,Map[abcd(sx,sy)].first));
      }
    }else if (c==2){
      for (int k=0;k<4;k++){
    sx=x+dx[k],sy=y+dy[k];
    if (Map.count(abcd(sx,sy)) && color(sx,sy)==3)
      link(Map[abcd(x,y)].second,Map[abcd(sx,sy)].second,1<<30);
      }
    }else if (c==3){
      link(Map[abcd(x,y)].second,T,Map[abcd(x,y)].first);
    }else if (c==4){
      link(S,Map[abcd(x,y)].second,Map[abcd(x,y)].first);
      for (int k=0;k<4;k++){
    sx=x+dx[k],sy=y+dy[k];
    if (Map.count(abcd(sx,sy)) && color(sx,sy)==1)
      link(Map[abcd(x,y)].second,Map[abcd(sx,sy)].second,1<<30);
      }
    }
  }
  printf("%d\n",Dinic());
  return 0;
}

你可能感兴趣的:(网络流)