zoukankan      html  css  js  c++  java
  • 【CF704D】Captain America

    跟着长郡军团做的一道题。

    题面

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

    题解

    上下界网络流傻逼题。

    注意判无解的第二种姿势:$l[i]>r[i]$

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<map>
    #define LL long long
    #define ri register int
    #define N 250000
    #define INF 1000000007
    using namespace std;
    
    int n,m,ccx=0,ccy=0,x[N],y[N];
    int p[N],le[N],re[N];
    int numx[N],numy[N];
    map<int,int> otx,oty;
    
    int idx(int x) {
      if (!otx.count(x)) otx[x]=++ccx;
      return otx[x];
    }
    int idy(int y) {
      if (!oty.count(y)) oty[y]=++ccy;
      return oty[y];
    }
    
    struct graph {
      vector<int> ed[N],w,to;
      int d[N],cur[N]; int S,T;
      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 main() {
      int t,l,d; LL r,b;
      scanf("%d %d",&n,&m);
      scanf("%lld %lld",&r,&b);
      for (ri i=1;i<=n;i++) {
        scanf("%d %d",&x[i],&y[i]);
        x[i]=idx(x[i]);y[i]=idy(y[i]);
        numx[x[i]]++; numy[y[i]]++;
      }
      for (ri i=1;i<=ccx;i++) le[i]=0,re[i]=numx[i];
      for (ri i=1;i<=ccy;i++) le[ccx+i]=0,re[ccx+i]=numy[i];
      for (ri i=1;i<=m;i++) {
        scanf("%d %d %d",&t,&l,&d);
        if (t==1) {
          if (!otx.count(l)) continue;
          int nx=otx[l]; l=otx[l];
          if ((numx[l]+d)%2==0) {
            le[nx]=max(le[nx],(numx[l]-d)/2);
            re[nx]=min(re[nx],(numx[l]+d)/2);
          }
          else {
            le[nx]=max(le[nx],(numx[l]-d+1)/2);
            re[nx]=min(re[nx],(numx[l]+d-1)/2);
          }
        }
        else {
          if (!oty.count(l)) continue;
          int ny=oty[l]+ccx; l=oty[l];
          if ((numy[l]+d)%2==0) {
            le[ny]=max(le[ny],(numy[l]-d)/2);
            re[ny]=min(re[ny],(numy[l]+d)/2);
          }
          else {
            le[ny]=max(le[ny],(numy[l]-d+1)/2);
            re[ny]=min(re[ny],(numy[l]+d-1)/2);
          }
        }
      }
      int S=0,T=ccx+ccy+1;
      int SS=ccx+ccy+2,TT=ccx+ccy+3;
      for (ri i=1;i<=ccx;i++) {
        if (re[i]<le[i]) {
          printf("-1");
          return 0;
        }
        p[S]-=le[i],p[i]+=le[i];
        G.add_edge(S,i,re[i]-le[i]);
      }
      for (ri i=ccx+1;i<=ccx+ccy;i++) {
        if (re[i]<le[i]) {
          printf("-1");
          return 0;
        }
        p[T]+=le[i],p[i]-=le[i];
        G.add_edge(i,T,re[i]-le[i]);
      }
      for (ri i=1;i<=n;i++) G.add_edge(x[i],ccx+y[i],1);
      int ds=0;
      for (ri i=S;i<=T;i++) {
        if (p[i]>0) G.add_edge(SS,i,p[i]),ds+=p[i];
        else if (p[i]<0) G.add_edge(i,TT,-p[i]);
      }
      G.add_edge(T,S,INF);
      G.S=SS; G.T=TT;
      int tm=G.dinic();
      if (tm!=ds) { printf("-1"); return 0;}
      int flow1=G.w[G.w.size()-1];
      G.w[G.w.size()-2]=G.w[G.w.size()-1]=0;
      for (ri i=0,l=G.w.size();i<l;i++) {
        if (G.to[i]==SS || G.to[i]==TT || G.to[i^1]==SS || G.to[i^1]==TT) G.w[i]=0;
      }
      G.S=S; G.T=T;
      int flow=flow1+G.dinic();
      if (r<b) {
        LL ans=r*1LL*flow+(n-flow)*1LL*b;
        printf("%lld
    ",ans);
        for (ri i=0,l=G.to.size();i<l;++i) {
          if (G.to[i]>ccx && G.to[i]<=ccx+ccy && G.to[i^1]>=1 && G.to[i^1]<=ccx) putchar(G.w[i]?'b':'r');
        }
      }
      else {
        LL ans=r*1LL*(n-flow)+b*1LL*flow;
        printf("%lld
    ",ans);
        for (ri i=0,l=G.to.size();i<l;++i) {
          if (G.to[i]>ccx && G.to[i]<=ccx+ccy && G.to[i^1]>=1 && G.to[i^1]<=ccx) putchar(G.w[i]?'r':'b');
        }
      }
      return 0;
    }
  • 相关阅读:
    关于R.styleable的问题
    Android游戏开发学习(5)--实现Button悬浮于与SurfaceView之上
    android悬浮按钮(Floating action button)的两种实现方法
    LinearLayout属性android:orientation
    Android详细的对话框AlertDialog.Builder使用方法
    SQLiteDatabase中query、insert、update、delete方法参数说明
    android原始sqlite中query的复杂用法
    Android加载手机磁盘上的资源---decodeFile方法的使用
    Laravel 5.2分页--怎么在一个页面实现两个以上的列表分页,互不影响?
    琐碎注意点⚠️
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11275036.html
Copyright © 2011-2022 走看看