zoukankan      html  css  js  c++  java
  • 【CQOI2017】老C的方块

    题面

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

    题解

    四分图$+$ 花式染色

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<vector>
    #include<map>
    #include<utility>
    #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;
    map<pair<int,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<ed[x].size();i++) {
            int e=ed[x][i];
            if (d[x]+1<d[to[e]] && 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<ed[x].size();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<<G.dinic()<<endl;
    }
  • 相关阅读:
    Linux下nginx 的常用命令
    Mybatis generator 自动生成代码(2)
    Android Retrofit2 网路编程
    Android webView输出自定义网页
    Android Studio OkHttpClient使用
    Android Studio SVN使用
    Android Toolbar的使用 顶部标题栏+后退键
    Android DrawLayout + ListView 的使用(一)
    RabbitMQ配置与安装
    Struts2拦截器
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11275073.html
Copyright © 2011-2022 走看看