【CQOI2017】老C的方块

题面

https://www.luogu.org/problem/P3756

题解

四分图$+$ 花式染色

#include
#include
#include
#include
#include
#include
#include
#define ri register int
#define N 200050
#define INF 1000000007
#define S 0
#define T (cc+1)
using namespace std;

const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int n,r,c,x[N],y[N],z[N];
int in[N],ou[N],cc;
mapint,int>,int> s;

struct graph {
  vector<int> ed[N];
  vector<int> w,to;
  int d[N],cur[N];
  void add_edge(int u,int v,int tw) {
    to.push_back(v); w.push_back(tw); ed[u].push_back(to.size()-1);
    to.push_back(u); w.push_back(0) ; ed[v].push_back(to.size()-1);
  }
  bool bfs() {
    queue<int> q;
    memset(d,0x3f,sizeof(d));
    d[S]=0; q.push(S);
    while (!q.empty()) {
      int x=q.front(); q.pop();
      for (ri i=0;i) {
        int e=ed[x][i];
        if (d[x]+1 w[e]) {
          d[to[e]]=d[x]+1;
          q.push(to[e]);
        }
      }
    }
    return d[T]<INF;
  }
  int dfs(int x,int limit) {
    if (x==T || limit==0) return limit;
    int sum=0; 
    for (ri &i=cur[x];i) {
      int e=ed[x][i];
      if (w[e] && d[x]+1==d[to[e]]) {
        int f=dfs(to[e],min(limit,w[e]));
        if (!f) continue;
        sum+=f; limit-=f; 
        w[e]-=f; w[1^e]+=f;
        if (!limit) return sum;
      }
    }
    return sum;
  }
  int dinic() {
    int ret=0;
    while (bfs()) {
      memset(cur,0,sizeof(cur));
      ret+=dfs(S,INF);
    }
    return ret;
  }
} G;

int col(int x,int y) {
  if (y%2==0) {
    if (x%4==0) return 4;
    else if (x%4==1) return 3;
    else if (x%4==2) return 2;
    else if (x%4==3) return 1;
  }
  else {
    if (x%4==0) return 3;
    else if (x%4==1) return 4;
    else if (x%4==2) return 1;
    else if (x%4==3) return 2;
  }
}

int main() {
  scanf("%d %d %d",&c,&r,&n);
  for (ri i=1;i<=n;i++) {
    scanf("%d %d %d",&x[i],&y[i],&z[i]);
    if (col(x[i],y[i])==3) ou[i]=in[i]=++cc;
    else if (col(x[i],y[i])==4) in[i]=++cc,ou[i]=++cc,G.add_edge(in[i],ou[i],z[i]);
    else if (col(x[i],y[i])==1) in[i]=++cc,ou[i]=++cc,G.add_edge(in[i],ou[i],z[i]);
    else if (col(x[i],y[i])==2) ou[i]=in[i]=++cc;
    s[make_pair(x[i],y[i])]=i;
  }
  for (ri i=1;i<=n;i++) {
    if (col(x[i],y[i])==3) G.add_edge(S,in[i],z[i]);
    else if (col(x[i],y[i])==2) G.add_edge(ou[i],T,z[i]);
  }
  int pe[5];
  pe[3]=4; pe[4]=1; pe[1]=2;
  for (ri i=1;i<=n;i++) if (col(x[i],y[i])!=2) {
    for (ri j=0;j<4;j++) {
      int nx=x[i]+dx[j],ny=y[i]+dy[j];
      int t=s[make_pair(nx,ny)];
      if (t>=1 && t<=n && col(nx,ny)==pe[col(x[i],y[i])]) G.add_edge(ou[i],in[t],INF);
    }
  }
  cout<endl;
}

 

转载于:https://www.cnblogs.com/shxnb666/p/11275073.html

你可能感兴趣的:(【CQOI2017】老C的方块)